package com.zkthink.ceres.order.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSON;
import com.alipay.api.domain.AlipayTradeAppPayModel;
import com.alipay.api.domain.AlipayTradeRefundApplyModel;
import com.alipay.api.response.AlipayTradeAppPayResponse;
import com.alipay.api.response.AlipayTradeRefundResponse;
import com.github.binarywang.wxpay.bean.order.WxPayAppOrderResult;
import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult;
import com.github.binarywang.wxpay.bean.order.WxPayNativeOrderResult;
import com.github.binarywang.wxpay.bean.request.WxPayOrderQueryRequest;
import com.github.binarywang.wxpay.bean.request.WxPayRefundRequest;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.bean.result.WxPayOrderQueryResult;
import com.github.binarywang.wxpay.constant.WxPayConstants;
import com.google.gson.Gson;
import com.zkthink.base.R;
import com.zkthink.base.service.SuperServiceImpl;
import com.zkthink.ceres.common.enums.RedSourceAdditionAndSubtractionTypeEnum;
import com.zkthink.ceres.common.enums.RedSourceTypeEnum;
import com.zkthink.ceres.common.enums.StoreDailyStatisticEnum;
import com.zkthink.ceres.common.enums.YesOrNoEnum;
import com.zkthink.ceres.common.service.SerialService;
import com.zkthink.ceres.finance.dto.DepositPromotionDTO;
import com.zkthink.ceres.finance.enums.DepositTypeEnum;
import com.zkthink.ceres.member.dao.MemberMapper;
import com.zkthink.ceres.member.dao.MemberRecommendMapper;
import com.zkthink.ceres.member.dto.AddressDTO;
import com.zkthink.ceres.member.entity.Member;
import com.zkthink.ceres.member.entity.MemberAddress;
import com.zkthink.ceres.member.service.MemberAddressService;
import com.zkthink.ceres.member.service.MemberService;
import com.zkthink.ceres.order.dao.*;
import com.zkthink.ceres.order.dto.*;
import com.zkthink.ceres.order.entity.*;
import com.zkthink.ceres.order.enums.*;
import com.zkthink.ceres.order.service.OrderProductService;
import com.zkthink.ceres.order.service.OrderService;
import com.zkthink.ceres.order.util.CreateBalanceJournalEvemtUtil;
import com.zkthink.ceres.order.util.Kd100TrackQueryAPI;
import com.zkthink.ceres.order.util.OrderEventUtil;
import com.zkthink.ceres.order.vo.*;
import com.zkthink.ceres.pay.service.PayService;
import com.zkthink.ceres.pay.wechat.v3.constants.WXPayConstants;
import com.zkthink.ceres.product.dto.IdQueryDTO;
import com.zkthink.ceres.product.dto.LogisticsCostDTO;
import com.zkthink.ceres.product.dto.PageQueryDTO;
import com.zkthink.ceres.product.entity.ProductSku;
import com.zkthink.ceres.product.entity.TenantProduct;
import com.zkthink.ceres.product.service.LogisticsService;
import com.zkthink.ceres.product.service.ProductService;
import com.zkthink.ceres.product.service.ProductSkuService;
import com.zkthink.ceres.product.vo.AdminProductVO;
import com.zkthink.ceres.promotion.dto.PromotionDetailDTO;
import com.zkthink.ceres.promotion.dto.PromotionInfoDTO;
import com.zkthink.ceres.promotion.entity.Coupon;
import com.zkthink.ceres.promotion.entity.PromotionStat;
import com.zkthink.ceres.promotion.enums.PromotionPlanEnum;
import com.zkthink.ceres.promotion.enums.PromotionTypeEnum;
import com.zkthink.ceres.promotion.service.CouponService;
import com.zkthink.ceres.promotion.service.MemberCouponService;
import com.zkthink.ceres.promotion.service.PromotionService;
import com.zkthink.ceres.promotion.service.PromotionStatService;
import com.zkthink.ceres.promotion.vo.web.CouponVO;
import com.zkthink.ceres.promotion.vo.web.PromotionVO;
import com.zkthink.ceres.shoppingcart.service.ShoppingCartService;
import com.zkthink.ceres.store.entity.Store;
import com.zkthink.ceres.store.service.StoreService;
import com.zkthink.context.BaseContextHandler;
import com.zkthink.database.mybatis.conditions.Wraps;
import com.zkthink.dozer.DozerUtils;
import com.zkthink.exception.BizException;
import com.zkthink.exception.code.ExceptionCode;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 业务实现类
 *
 * </p>
 *
 * @author JustArgo
 * @date 2020-05-10
 */
@Slf4j
@Service
@AllArgsConstructor
public class OrderServiceImpl extends SuperServiceImpl<OrderMapper, Order> implements OrderService {

    private MemberMapper memberMapper;


    private MemberRecommendMapper memberRecommendMapper;

    private SerialService serialService;

    private ProductSkuService productSkuService;

    private ProductService productService;

    private OrderProductMapper orderProductMapper;



    @Autowired
    private ApplicationEventPublisher publisher;
    //private OrderPaymentMapper orderPaymentMapper;

    private MoneyReturnMapper moneyReturnMapper;

    private MoneyReturnActionHistoryMapper moneyReturnActionHistoryMapper;

    private GoodsReturnMapper goodsReturnMapper;

    private GoodsReturnActionHistoryMapper goodsReturnActionHistoryMapper;

    private ReturnInterventionMapper returnInventionMapper;

    private DozerUtils dozerUtils;

    private MemberAddressService memberAddressService;

    private StoreService storeService;

    private LogisticsService logisticsService;

    private MemberService memberService;

    private PayService payService;

    private ShoppingCartService shoppingCartService;

    private PromotionService promotionService;

    private CouponService couponService;

    private MemberCouponService memberCouponService;

    private PromotionStatService promotionStatService;


    private Kd100TrackQueryAPI kd100TrackQueryAPI;

    private CommentMapper commentMapper;

    private OrderEventUtil orderEventUtil;
    private CreateBalanceJournalEvemtUtil createBalanceJournalEvemtUtil;



    @Override
    @Transactional
    public R<PlaceOrderVO> placeOrder(PlaceOrderDTO placeOrderDTO) {
        Long userId = BaseContextHandler.getUserId();

        Long mid = placeOrderDTO.getMid();
        List<OrderSkuItemDTO> skuItemDTOList = placeOrderDTO.getSkuItemDTOList();
        String notes = placeOrderDTO.getNotes();
        Long addressId = placeOrderDTO.getAddressId();
        String ip = placeOrderDTO.getIp();
        Integer source = placeOrderDTO.getSource();
        Integer payChannel = placeOrderDTO.getPayChannel();
        PromotionInfoDTO promotionInfoDTO = placeOrderDTO.getPromotionInfoDTO();
        PlaceOrderVO placeOrderVO = new PlaceOrderVO();

        Member member = memberService.getById(mid);
        //判断参数是否合法
        if (mid == null || mid <= 0 || skuItemDTOList == null || skuItemDTOList.size() == 0 || member == null) {
            return R.fail("参数错误，下单失败");
        }

        for (OrderSkuItemDTO skuItemDTO : skuItemDTOList) {
            if (skuItemDTO.getBuyNum() <= 0) {
                return R.fail("商品购买数量必须大于0");
            }
        }

        Order parentOrder = new Order();

        try {
            List<Order> childOrders = new ArrayList<Order>();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmddSSS");
            //用于存放 相同店铺 订单商品对象
            Map<Long, List<OrderProduct>> storeIdOrderMap = new HashMap<Long, List<OrderProduct>>();
            //用于存放店铺id和商户编码的对应关系
            Map<Long, String> storeIdTenantCodeMap = new HashMap<Long, String>();
            Map<String, List<OrderProduct>> orderCodeOrderProductsMap = new HashMap<String, List<OrderProduct>>();


            parentOrder.setParentId(0L);
            parentOrder.setTenantCode("-1");
            parentOrder.setOrderCode(serialService.next("", 32));
            parentOrder.setOrderStatus(OrderStatusEnum.NO_PAY.getCode());            //订单状态
            parentOrder.setPayStatus(PayStatusEnum.NO_PAY.getCode());            //支付状态
            parentOrder.setReturnType(ReturnTypeEnum.NO_RETURN.getCode());
            parentOrder.setPayChannel(payChannel);

            //设置收货地址
            parentOrder = this.setReceAdd(mid, parentOrder, addressId);
            parentOrder.setCreateTime(LocalDateTime.now());
            //parentOrder.setOrderSum(sum);
            parentOrder.setNotes(notes);
            parentOrder.setMemberAccount(member.getNickname() + "_" + member.getAccount());
            parentOrder.setMid(mid);

            /*if(promotionInfoDTO!=null){
                parentOrder.setPromotionId(promotionInfoDTO.getPromotionId());
                parentOrder.setCouponId(promotionInfoDTO.getCouponId());
            }*/

            //插入父订单 并返回ID
            baseMapper.insert(parentOrder);
            placeOrderVO.setOrderId(parentOrder.getId());
            //库存不足的sku
            List<String> insufficientSkuNames = new ArrayList<String>();

            Map<Long, ProductSku> skuMap = new HashMap<Long, ProductSku>();
            Map<Long, TenantProduct> tenantProductMap = new HashMap<Long, TenantProduct>();
            //商品id的集合
            Set<Long> productIdSet = new HashSet<Long>();
            for (OrderSkuItemDTO skuItemDTO : skuItemDTOList) {
                Long skuId = skuItemDTO.getSkuId();
                Integer buyNum = skuItemDTO.getBuyNum();
                ProductSku sku = productSkuService.getById(skuId);
                skuMap.put(skuId, sku);
                if (tenantProductMap.get(sku.getProductId()) == null) {
                    TenantProduct tenantProduct = productService.getByIdWithTenant(sku.getProductId());
                    tenantProductMap.put(tenantProduct.getId(), tenantProduct);
                }
                TenantProduct tenantProduct = tenantProductMap.get(sku.getProductId());
                productIdSet.add(tenantProduct.getId());
                if (sku.getSkuStock() < buyNum && tenantProduct.getOversold() != null && tenantProduct.getOversold() == 0) {
                    insufficientSkuNames.add(tenantProduct.getProductName() + ": " + sku.getSkuNameStr());
                }
            }

            if (insufficientSkuNames.size() > 0) {
                return R.fail("以下商品库存不足：" + StringUtils.join(insufficientSkuNames, ","));
            }

            Map<Long, Integer> productSellCountMap = new HashMap<Long, Integer>();

            //处理子订单  关于运费  不同的sku有不同的计算过程
            for (OrderSkuItemDTO skuItemDTO : skuItemDTOList) {
                Long skuId = skuItemDTO.getSkuId();
                Integer buyNum = skuItemDTO.getBuyNum();
                //找出sku 及其对应的商品 以及供应商
                ProductSku sku = skuMap.get(skuId);
                TenantProduct product = tenantProductMap.get(sku.getProductId());

                if (product.getStatus() != 1) {
                    return R.fail("下单失败,商品不可用");
                }

                productIdSet.add(product.getId());

                OrderProduct orderProduct = new OrderProduct();
                orderProduct.setTenantCode(product.getTenantCode());
                orderProduct.setProductId(product.getId());
                orderProduct.setProductName(product.getProductName());
                orderProduct.setSkuId(skuId);

                orderProduct.setBuyNum(buyNum);
                orderProduct.setWeight(sku.getWeight());
                orderProduct.setSkuNameStr(sku.getSkuNameStr());
                orderProduct.setSkuImg(sku.getSkuImg());

                orderProduct.setApplyPrice(sku.getApplyPrice());
                orderProduct.setSellPrice(sku.getSkuPrice());
                orderProduct.setDiscountAmount(0L);

                //更新sku的库存
                productSkuService.updateSkuStock(sku.getId(), buyNum * -1);

                //统计本次商品的销量
                productSellCountMap.put(product.getId(), productSellCountMap.getOrDefault(product.getId(), 0) + buyNum);

                if (storeIdOrderMap.containsKey(product.getStoreId())) {
                    storeIdOrderMap.get(product.getStoreId()).add(orderProduct);
                } else {
                    List<OrderProduct> orderProducts = new ArrayList<OrderProduct>();
                    orderProducts.add(orderProduct);
                    storeIdOrderMap.put(product.getStoreId(), orderProducts);
                }
                if (!storeIdTenantCodeMap.containsKey(product.getStoreId())) {
                    storeIdTenantCodeMap.put(product.getStoreId(), product.getTenantCode());
                }
            }

            //商品是否参与了活动
            Map<Long, Boolean> matchMap = new HashMap<Long, Boolean>();

            //根据选择的活动计算优惠，此处把每个sku该均摊的优惠都计算了，下面计算子订单的时候，会扣减，所以不用返回总的优惠
            calcDiscountAmount(mid, storeIdOrderMap, promotionInfoDTO, matchMap);

            Map<String, Order> childOrderMap = new HashMap<String, Order>();

            //以下for循环 基于  同一供应商同一货仓 此时一个子订单可以对应多个 订单商品
            for (Map.Entry<Long, List<OrderProduct>> entry : storeIdOrderMap.entrySet()) {

                Long storeId = entry.getKey();

                List<OrderProduct> orderProducts = entry.getValue();

                Order childOrder = new Order();
                childOrder.setParentCode(parentOrder.getOrderCode());

                //设置商户编码
                String tenantCode = storeIdTenantCodeMap.get(storeId);
                childOrder.setTenantCode(tenantCode);

                //设置订单的各项状态   由于同一个供应商 的同一个货仓 可能有 多个订单商品  所以 有些状态无法设置
                childOrder.setOrderStatus(parentOrder.getOrderStatus());            //订单状态
                childOrder.setPayStatus(parentOrder.getPayStatus());                //支付状态
                childOrder.setReturnType(parentOrder.getReturnType());
                childOrder.setNotes(notes);                                         //备注
                childOrder.setMemberAccount(parentOrder.getMemberAccount());
                childOrder.setPayChannel(parentOrder.getPayChannel());

                //设置订单号
                childOrder.setOrderCode(serialService.next("", 32));

                //子订单 也要 设置收货地址
                childOrder.setCountry(parentOrder.getCountry());
                childOrder.setCountryId(parentOrder.getCountryId());
                childOrder.setProvince(parentOrder.getProvince());
                childOrder.setProvinceId(parentOrder.getProvinceId());
                childOrder.setCity(parentOrder.getCity());
                childOrder.setCityId(parentOrder.getCityId());
                childOrder.setDistrict(parentOrder.getDistrict());
                childOrder.setDistrictId(parentOrder.getDistrictId());
                childOrder.setAddress(parentOrder.getAddress());

                //设置店铺id
                Store store = storeService.getById(storeId);
                childOrder.setStoreId(storeId);
                childOrder.setStoreName(store.getStoreName());

                //设置创建时间
                childOrder.setCreateTime(LocalDateTime.now());

                //设置下单用户的ID
                childOrder.setMid(mid);

                childOrder.setRecName(parentOrder.getRecName());
                childOrder.setRecMobile(parentOrder.getRecMobile());

                Long childOrderSum = 0L;            //子订单金额
                Long childOrderDiscountAmount = 0L;
                boolean hasDiscount = false;

                for (int i = 0; i < orderProducts.size(); i++) {
                    childOrderSum += orderProducts.get(i).getBuyNum() * orderProducts.get(i).getSellPrice();
                    childOrderDiscountAmount += orderProducts.get(i).getDiscountAmount();
                    Boolean matched = matchMap.get(orderProducts.get(i).getProductId());
                    if (matched == null) {
                        matched = false;
                    }
                    if (promotionInfoDTO != null && matched) {
                        hasDiscount = true;
                    }
                }

                childOrder.setOrderSum(childOrderSum);
                childOrder.setDiscountAmount(childOrderDiscountAmount);

                childOrders.add(childOrder);

                //如果子订单内的商品参加了活动
                if (hasDiscount) {
                    PromotionStat promotionStat = new PromotionStat();
                    promotionStat.setPromotionId(promotionInfoDTO.getPromotionId());
                    promotionStat.setTenantCode(tenantCode);
                    promotionStat.setMid(mid);
                    promotionStat.setOrderCode(childOrder.getOrderCode());
                    promotionStat.setOrderSum(childOrder.getOrderSum());
                    promotionStatService.addPromotionStat(promotionStat);

                    childOrder.setPromotionId(parentOrder.getPromotionId());
                    childOrder.setCouponId(parentOrder.getCouponId());
                }

                orderCodeOrderProductsMap.put(childOrder.getOrderCode(), orderProducts);
                childOrderMap.put(childOrder.getOrderCode(), childOrder);
            }

            List<SimpleChildOrderDTO> orderInfoList = new ArrayList<>();

            Map<String, Long> orderCodePostFeeMap = new HashMap<String, Long>();
            for (Map.Entry<String, List<OrderProduct>> entry : orderCodeOrderProductsMap.entrySet()) {
                List<OrderProductDTO> orderProductDTOList = dozerUtils.mapList(entry.getValue(), OrderProductDTO.class);
                Order childOrder = childOrderMap.get(entry.getKey());

                String tenantCode = childOrder.getTenantCode();
                String province = parentOrder.getProvince();
                String city = parentOrder.getCity();
                LogisticsCostDTO costDTO = logisticsService.getSuitableLogisticsCost(tenantCode, province, city, orderProductDTOList);
                long childOrderPostFee = 0L;

                if (costDTO != null) {
                    childOrderPostFee = costDTO.getCost();
                    childOrder.setLogisticsCase(costDTO.getName());
                }

                childOrder.setPostFee(childOrderPostFee);
                childOrder.setOrderSum(childOrder.getOrderSum() + childOrderPostFee);

                SimpleChildOrderDTO simpleChildOrderDTO = new SimpleChildOrderDTO();
                simpleChildOrderDTO.setId(childOrder.getId());
                simpleChildOrderDTO.setOrderCode(childOrder.getOrderCode());
                simpleChildOrderDTO.setOrderSum(childOrder.getOrderSum());
                orderInfoList.add(simpleChildOrderDTO);
            }

            Long totalPostFee = 0L;
            Long totalOrderSum = 0L;
            Long totalDiscountAmount = 0L;

            for (int i = 0; i < childOrders.size(); i++) {
                Order childOrder = childOrders.get(i);
                childOrder.setParentId(parentOrder.getId());


                baseMapper.insert(childOrder);
                List<OrderProduct> orderProducts = orderCodeOrderProductsMap.get(childOrder.getOrderCode());
                for (int j = 0; j < orderProducts.size(); j++) {
                    OrderProduct op = orderProducts.get(j);
                    op.setOrderId(childOrder.getId());
                    op.setStoreId(childOrder.getStoreId());
//                    op.setShareMid(placeOrderDTO.getShareMid());
                    //orderProductMapper.insert(orderProducts.get(j));
                    orderProductMapper.insert(op);
                }


                totalPostFee += childOrder.getPostFee();
                totalOrderSum += childOrder.getOrderSum();
                totalDiscountAmount += childOrder.getDiscountAmount();
            }

            //重新统计商品库存
            productService.updateStock(productIdSet);
            if (source == 1) {
                List<Long> skuIdList = new ArrayList<Long>();
                for (OrderSkuItemDTO skuDto : skuItemDTOList) {
                    skuIdList.add(skuDto.getSkuId());
                }
                //下单后清除购物车内对应的商品
                shoppingCartService.deletePartOfSkuFromShoppingCart(mid, skuIdList);
            }

            parentOrder.setPostFee(totalPostFee);
            parentOrder.setOrderSum(totalOrderSum);
            parentOrder.setDiscountAmount(totalDiscountAmount);


            //计算客户总共要付的小红心：总价格（付款价格加上邮费）减去优惠
            long payLoveNum = (totalOrderSum - totalDiscountAmount) / 100;
            //得到客户的小红心数目
//            BigDecimal giftNum = member.getGiftNum();
//            if (giftNum == null || giftNum.compareTo(new BigDecimal(payLoveNum)) < 0) {
//                return R.fail("小红心不足");
//            }
            //TODO 减去小红心
//            XsyMemberLoveHis xsyMemberLoveHis = new XsyMemberLoveHis();
//            xsyMemberLoveHis.setRedAdditionAndSubtractionType(RedSourceAdditionAndSubtractionTypeEnum.SUBTRACTION.getCode());
//            xsyMemberLoveHis.setRedHeart(new BigDecimal(parentOrder.getOrderSum() / 100));
//            xsyMemberLoveHis.setRedTime(LocalDateTime.now());
//            xsyMemberLoveHis.setRedType(RedSourceTypeEnum.BUY_GOOD.getCode());
//            xsyMemberLoveHis.setMid(userId);
//            xsyMemberLoveHisService.addxsyMemberLoveHis(xsyMemberLoveHis);
            //TODO 订单改变状态
            PayOrderCallbackDTO payOrderCallbackDTO = new PayOrderCallbackDTO();
            payOrderCallbackDTO.setOrderCode(parentOrder.getOrderCode());
            payOrderCallbackDTO.setPayTime(LocalDateTime.now());
            payOrderCallbackDTO.setPayNum(parentOrder.getOrderCode());
            payOrderCallBack(payOrderCallbackDTO);
            //更新商品的销量
            productService.updateSellCount(productSellCountMap);
            //埋点
            storeService.addStorePoint(childOrders.stream().map(Order::getStoreId).collect(
                    Collectors.toList()), StoreDailyStatisticEnum.PAY_SUCCESS);
            placeOrderVO.setObject(parentOrder);
            return R.success(placeOrderVO);

        } catch (Exception e) {
            log.error("下单失败：" + e.getMessage(), e);
            return R.fail("下单失败");
        }
    }


    @Override
    public R<OrderListVO> findSalesOrderList(FindOrderListDTO findOrderListDTO) {
        //参数不能为空, 并且限制超过每页50个
        if (findOrderListDTO == null || findOrderListDTO.getMid() == null || findOrderListDTO.getPageSize() > 50) {
            return R.fail("参数错误");
        }
        //这里的订单状态，为前端页面的展示状态，和实际数据中的状态有点差别
        int orderStatus = findOrderListDTO.getOrderStatus();
        // 0-全部 1-待付款 2-待发货 3-待收货 4-已完成 其它值默认也是查全部
        List<Order> orderList = new ArrayList<Order>();
        Integer total = 0;

        OrderStatusEnum statusEnum = OrderStatusEnum.findByCode(orderStatus);
//        total = baseMapper.findSalesOrderListByStatusAndPageCount(findOrderListDTO.getMid(), statusEnum != null ? statusEnum.getCode() : null);
//        orderList = baseMapper.findSalesOrderListByStatusAndPage(findOrderListDTO.getMid(), statusEnum != null ? statusEnum.getCode() : null,
//                (findOrderListDTO.getPageIndex() - 1) * findOrderListDTO.getPageSize(), findOrderListDTO.getPageSize());

        List<OrderVO> orderVOList = new ArrayList<>();

        for (Order order : orderList) {
            OrderVO orderVO = dozerUtils.map(order, OrderVO.class);
            orderVO.setId(order.getId());
            List<OrderProduct> orderProductList = orderProductMapper.selectList(Wraps.<OrderProduct>lbQ().eq(OrderProduct::getOrderId, order.getId()));
            List<OrderProductVO> orderProductVOList = dozerUtils.mapList(orderProductList, OrderProductVO.class);

            //如果有退款单 或者 退货单，则查询出来
            Integer returnType = order.getReturnType();
            if (returnType != null) {
                if (returnType == ReturnTypeEnum.RETURN_MONEY.getCode()) {
                    List<MoneyReturn> moneyReturnList = moneyReturnMapper.selectList(Wraps.<MoneyReturn>lbQ().eq(MoneyReturn::getOrderId, order.getId()).eq(MoneyReturn::getCurrentVersion, 0));
                    orderVO.setMoneyReturnList(moneyReturnList);
                } else if (returnType == ReturnTypeEnum.RETURN_GOODS.getCode()) {
                    List<GoodsReturn> goodsReturnList = goodsReturnMapper.selectList(Wraps.<GoodsReturn>lbQ().eq(GoodsReturn::getOrderId, order.getId()).eq(GoodsReturn::getCurrentVersion, 0));
                    orderVO.setGoodsReturnList(goodsReturnList);
                }
            }
            if (orderVO.getOrderStatus() == OrderStatusEnum.NO_PAY.getCode()) {
                orderVO.setOverTime(order.getCreateTime().plusHours(2));
            }

            //如果订单已完成，并且距离完成时间10天之内，设置商品的评价状态
            for (OrderProductVO op : orderProductVOList) {
                //如果不是已完成，直接设置 忽略评价状态
                if (order.getOrderStatus() != OrderStatusEnum.FINISH.getCode()) {
                    op.setCommentStatus(CommentStatusEnum.NOT_STATUS.getCode());
                } else {
                    //代表这个订单距离下单日期已经超过15天了,目前超过15天是不允许再评价了
                    if (order.getCreateTime().plusDays(10).isBefore(LocalDateTime.now())) {
                        op.setCommentStatus(CommentStatusEnum.NOT_STATUS.getCode());
                    } else {
                        Comment comment = commentMapper.selectOne(Wraps.<Comment>lbQ().eq(Comment::getMid, findOrderListDTO.getMid()).eq(Comment::getOrderProductId, op.getId()).eq(Comment::getBizType, CommentTypeEnum.NORMAL.getCode()));
                        if (comment != null) {
                            op.setCommentStatus(CommentStatusEnum.COMMENTED.getCode());
                            Comment additionalComment = commentMapper.selectOne(Wraps.<Comment>lbQ().eq(Comment::getMid, findOrderListDTO.getMid())
                                    .eq(Comment::getParentId, comment.getId())
                                    .eq(Comment::getBizType, CommentTypeEnum.ADDITIONAL.getCode()));
                            op.setComment(comment);
                            op.setAdditionalComment(additionalComment);
                        } else {
                            op.setCommentStatus(CommentStatusEnum.WAITING_COMMENT.getCode());
                        }
                    }
                }
            }
            orderVO.setOrderProductVOList(orderProductVOList);
            orderVOList.add(orderVO);
        }

        OrderListVO orderListVO = new OrderListVO();
        orderListVO.setTotal(total);
        orderListVO.setOrderVOList(orderVOList);

        return R.success(orderListVO);
    }

    //更新诺金 订单状态
    private void updateCoinOrderToPayed(Order order, Long payNum) {
        try {
            PayOrderCallbackDTO payOrderCallbackDTO = new PayOrderCallbackDTO();
            payOrderCallbackDTO.setOrderCode(order.getOrderCode());
            payOrderCallbackDTO.setPayTime(LocalDateTime.now());
            payOrderCallbackDTO.setPayNum(String.valueOf(payNum));
            payOrderCallBack(payOrderCallbackDTO);
        } catch (Exception e) {
            log.error("支付通知回调-订单回调异常,单号: [{}]", order.getOrderCode(), e);
            throw new BizException("支付通知回调-订单回调异常");
        }
    }

    //    @Override
//    public R<Object> placeOrderCoin(PlaceOrderDTO placeOrderDTO) {
//        String payPassword = "123456";
//        Long mid = placeOrderDTO.getMid();
//        List<OrderSkuItemDTO> skuItemDTOList = placeOrderDTO.getSkuItemDTOList();
//        String notes = placeOrderDTO.getNotes();
//        Long addressId = placeOrderDTO.getAddressId();
//        String ip = placeOrderDTO.getIp();
//        Integer source = placeOrderDTO.getSource();
//        Integer payChannel = placeOrderDTO.getPayChannel();
//        PromotionInfoDTO promotionInfoDTO = placeOrderDTO.getPromotionInfoDTO();
//
//        //判断参数是否合法
//        if (mid == null || mid <= 0 || skuItemDTOList == null || skuItemDTOList.size() == 0) {
//            return R.fail("参数错误，下单失败");
//        }
//
//        for (OrderSkuItemDTO skuItemDTO : skuItemDTOList) {
//            if (skuItemDTO.getBuyNum() <= 0) {
//                return R.fail("商品购买数量必须大于0");
//            }
//        }
//
//        Order parentOrder = new Order();
//
//        try {
//            List<Order> childOrders = new ArrayList<Order>();
//            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmddSSS");
//            //用于存放 相同店铺 订单商品对象
//            Map<Long, List<OrderProduct>> storeIdOrderMap = new HashMap<Long, List<OrderProduct>>();
//            //用于存放店铺id和商户编码的对应关系
//            Map<Long, String> storeIdTenantCodeMap = new HashMap<Long, String>();
//            Map<String, List<OrderProduct>> orderCodeOrderProductsMap = new HashMap<String, List<OrderProduct>>();
//
//            Member member = memberService.getById(mid);
//
//            parentOrder.setParentId(0L);
//            parentOrder.setTenantCode("-1");
//            parentOrder.setOrderCode(serialService.next("", 32));
//            parentOrder.setOrderStatus(OrderStatusEnum.NO_PAY.getCode());            //订单状态
//            parentOrder.setPayStatus(PayStatusEnum.NO_PAY.getCode());            //支付状态
//            parentOrder.setReturnType(ReturnTypeEnum.NO_RETURN.getCode());
//            parentOrder.setPayChannel(payChannel);
//
//            //设置收货地址
//            parentOrder = this.setReceAdd(mid, parentOrder, addressId);
//            parentOrder.setCreateTime(LocalDateTime.now());
//            //parentOrder.setOrderSum(sum);
//            parentOrder.setNotes(notes);
//            parentOrder.setMemberAccount(member.getNickname() + "_" + member.getOpenid());
//
//            parentOrder.setMid(mid);
//
//            /*if(promotionInfoDTO!=null){
//                parentOrder.setPromotionId(promotionInfoDTO.getPromotionId());
//                parentOrder.setCouponId(promotionInfoDTO.getCouponId());
//            }*/
//
//            //插入父订单 并返回ID
//            baseMapper.insert(parentOrder);
//
//            //库存不足的sku
//            List<String> insufficientSkuNames = new ArrayList<String>();
//
//            Map<Long, ProductSku> skuMap = new HashMap<Long, ProductSku>();
//            Map<Long, TenantProduct> tenantProductMap = new HashMap<Long, TenantProduct>();
//            //商品id的集合
//            Set<Long> productIdSet = new HashSet<Long>();
//            for (OrderSkuItemDTO skuItemDTO : skuItemDTOList) {
//                Long skuId = skuItemDTO.getSkuId();
//                Integer buyNum = skuItemDTO.getBuyNum();
//                ProductSku sku = productSkuService.getById(skuId);
//                skuMap.put(skuId, sku);
//                if (tenantProductMap.get(sku.getProductId()) == null) {
//                    TenantProduct tenantProduct = productService.getByIdWithTenant(sku.getProductId());
//                    tenantProductMap.put(tenantProduct.getId(), tenantProduct);
//                }
//                TenantProduct tenantProduct = tenantProductMap.get(sku.getProductId());
//                productIdSet.add(tenantProduct.getId());
//                if (sku.getSkuStock() < buyNum && tenantProduct.getOversold() != null && tenantProduct.getOversold() == 0) {
//                    insufficientSkuNames.add(tenantProduct.getProductName() + ": " + sku.getSkuNameStr());
//                }
//            }
//
//            if (insufficientSkuNames.size() > 0) {
//                return R.fail("以下商品库存不足：" + StringUtils.join(insufficientSkuNames, ","));
//            }
//
//            Map<Long, Integer> productSellCountMap = new HashMap<Long, Integer>();
//
//            //判断商品是否是诺金购买
//            int coinNum = 0;
//            //处理子订单  关于运费  不同的sku有不同的计算过程
//            for (OrderSkuItemDTO skuItemDTO : skuItemDTOList) {
//                Long skuId = skuItemDTO.getSkuId();
//                Integer buyNum = skuItemDTO.getBuyNum();
//                //找出sku 及其对应的商品 以及供应商
//                ProductSku sku = skuMap.get(skuId);
//                TenantProduct product = tenantProductMap.get(sku.getProductId());
//                if ("2".equals(product.getProductType())) {
//                    coinNum = coinNum + 1;
//                }
//
//                productIdSet.add(product.getId());
//
//                OrderProduct orderProduct = new OrderProduct();
//                orderProduct.setTenantCode(product.getTenantCode());
//                orderProduct.setProductId(product.getId());
//                orderProduct.setProductName(product.getProductName());
//                orderProduct.setSkuId(skuId);
//
//                orderProduct.setBuyNum(buyNum);
//                orderProduct.setWeight(sku.getWeight());
//                orderProduct.setSkuNameStr(sku.getSkuNameStr());
//                orderProduct.setSkuImg(sku.getSkuImg());
//
//                orderProduct.setApplyPrice(sku.getApplyPrice());
//                orderProduct.setSellPrice(sku.getSkuPrice());
//                orderProduct.setDiscountAmount(0L);
//
//                //更新sku的库存
//                productSkuService.updateSkuStock(sku.getId(), buyNum * -1);
//
//                //统计本次商品的销量
//                productSellCountMap.put(product.getId(), productSellCountMap.getOrDefault(product.getId(), 0) + buyNum);
//
//                if (storeIdOrderMap.containsKey(product.getStoreId())) {
//                    storeIdOrderMap.get(product.getStoreId()).add(orderProduct);
//                } else {
//                    List<OrderProduct> orderProducts = new ArrayList<OrderProduct>();
//                    orderProducts.add(orderProduct);
//                    storeIdOrderMap.put(product.getStoreId(), orderProducts);
//                }
//                if (!storeIdTenantCodeMap.containsKey(product.getStoreId())) {
//                    storeIdTenantCodeMap.put(product.getStoreId(), product.getTenantCode());
//                }
//            }
//
//            //商品是否参与了活动
//            Map<Long, Boolean> matchMap = new HashMap<Long, Boolean>();
//            //根据选择的活动计算优惠，此处把每个sku该均摊的优惠都计算了，下面计算子订单的时候，会扣减，所以不用返回总的优惠
//            calcDiscountAmount(mid, storeIdOrderMap, promotionInfoDTO, matchMap);
//
//            Map<String, Order> childOrderMap = new HashMap<String, Order>();
//
//            //以下for循环 基于  同一供应商同一货仓 此时一个子订单可以对应多个 订单商品
//            for (Map.Entry<Long, List<OrderProduct>> domain : storeIdOrderMap.entrySet()) {
//
//                Long storeId = domain.getKey();
//
//                List<OrderProduct> orderProducts = domain.getValue();
//
//                Order childOrder = new Order();
//                childOrder.setParentCode(parentOrder.getOrderCode());
//
//                //设置商户编码
//                String tenantCode = storeIdTenantCodeMap.get(storeId);
//                childOrder.setTenantCode(tenantCode);
//
//                //设置订单的各项状态   由于同一个供应商 的同一个货仓 可能有 多个订单商品  所以 有些状态无法设置
//                childOrder.setOrderStatus(parentOrder.getOrderStatus());            //订单状态
//                childOrder.setPayStatus(parentOrder.getPayStatus());                //支付状态
//                childOrder.setReturnType(parentOrder.getReturnType());
//                childOrder.setNotes(notes);                                         //备注
//                childOrder.setMemberAccount(parentOrder.getMemberAccount());
//                childOrder.setPayChannel(parentOrder.getPayChannel());
//
//                //设置订单号
//                childOrder.setOrderCode(serialService.next("", 32));
//
//                //子订单 也要 设置收货地址
//                childOrder.setCountry(parentOrder.getCountry());
//                childOrder.setCountryId(parentOrder.getCountryId());
//                childOrder.setProvince(parentOrder.getProvince());
//                childOrder.setProvinceId(parentOrder.getProvinceId());
//                childOrder.setCity(parentOrder.getCity());
//                childOrder.setCityId(parentOrder.getCityId());
//                childOrder.setDistrict(parentOrder.getDistrict());
//                childOrder.setDistrictId(parentOrder.getDistrictId());
//                childOrder.setAddress(parentOrder.getAddress());
//
//                //设置店铺id
//                Store server = storeService.getById(storeId);
//                childOrder.setStoreId(storeId);
//                childOrder.setStoreName(server.getStoreName());
//
//                //设置创建时间
//                childOrder.setCreateTime(LocalDateTime.now());
//
//                //设置下单用户的ID
//                childOrder.setMid(mid);
//
//                childOrder.setRecName(parentOrder.getRecName());
//                childOrder.setRecMobile(parentOrder.getRecMobile());
//
//                Long childOrderSum = 0L;            //子订单金额
//                Long childOrderDiscountAmount = 0L;
//                boolean hasDiscount = false;
//
//                for (int i = 0; i < orderProducts.size(); i++) {
//                    childOrderSum += orderProducts.get(i).getBuyNum() * orderProducts.get(i).getSellPrice();
//                    childOrderDiscountAmount += orderProducts.get(i).getDiscountAmount();
//                    Boolean matched = matchMap.get(orderProducts.get(i).getProductId());
//                    if (matched == null) {
//                        matched = false;
//                    }
//                    if (promotionInfoDTO != null && matched) {
//                        hasDiscount = true;
//                    }
//                }
//
//                childOrder.setOrderSum(childOrderSum);
//                childOrder.setDiscountAmount(childOrderDiscountAmount);
//
//                childOrders.add(childOrder);
//
//                //如果子订单内的商品参加了活动
//                if (hasDiscount) {
//                    PromotionStat promotionStat = new PromotionStat();
//                    promotionStat.setPromotionId(promotionInfoDTO.getPromotionId());
//                    promotionStat.setTenantCode(tenantCode);
//                    promotionStat.setMid(mid);
//                    promotionStat.setOrderCode(childOrder.getOrderCode());
//                    promotionStat.setOrderSum(childOrder.getOrderSum());
//                    promotionStatService.addPromotionStat(promotionStat);
//
//                    childOrder.setPromotionId(parentOrder.getPromotionId());
//                    childOrder.setCouponId(parentOrder.getCouponId());
//                }
//
//                orderCodeOrderProductsMap.put(childOrder.getOrderCode(), orderProducts);
//                childOrderMap.put(childOrder.getOrderCode(), childOrder);
//            }
//
//            List<SimpleChildOrderDTO> orderInfoList = new ArrayList<>();
//
//            Map<String, Long> orderCodePostFeeMap = new HashMap<String, Long>();
//            for (Map.Entry<String, List<OrderProduct>> domain : orderCodeOrderProductsMap.entrySet()) {
//                List<OrderProductDTO> orderProductDTOList = dozerUtils.mapList(domain.getValue(), OrderProductDTO.class);
//                Order childOrder = childOrderMap.get(domain.getKey());
//
//                String tenantCode = childOrder.getTenantCode();
//                String province = parentOrder.getProvince();
//                String city = parentOrder.getCity();
//                LogisticsCostDTO costDTO = logisticsService.getSuitableLogisticsCost(tenantCode, province, city, orderProductDTOList);
//                long childOrderPostFee = 0L;
//
//                if (costDTO != null) {
//                    childOrderPostFee = costDTO.getCost();
//                    childOrder.setLogisticsCase(costDTO.getName());
//                }
//
//                childOrder.setPostFee(childOrderPostFee);
//                childOrder.setOrderSum(childOrder.getOrderSum() + childOrderPostFee);
//
//                SimpleChildOrderDTO simpleChildOrderDTO = new SimpleChildOrderDTO();
//                simpleChildOrderDTO.setId(childOrder.getId());
//                simpleChildOrderDTO.setOrderCode(childOrder.getOrderCode());
//                simpleChildOrderDTO.setOrderSum(childOrder.getOrderSum());
//                orderInfoList.add(simpleChildOrderDTO);
//            }
//
//            Long totalPostFee = 0L;
//            Long totalOrderSum = 0L;
//            Long totalDiscountAmount = 0L;
//
//            for (int i = 0; i < childOrders.size(); i++) {
//                Order childOrder = childOrders.get(i);
//                childOrder.setParentId(parentOrder.getId());
//                baseMapper.insert(childOrder);
//                List<OrderProduct> orderProducts = orderCodeOrderProductsMap.get(childOrder.getOrderCode());
//                for (int j = 0; j < orderProducts.size(); j++) {
//                    OrderProduct op = orderProducts.get(j);
//                    op.setOrderId(childOrder.getId());
//                    op.setStoreId(childOrder.getStoreId());
//                    orderProductMapper.insert(orderProducts.get(j));
//                }
//                totalPostFee += childOrder.getPostFee();
//                totalOrderSum += childOrder.getOrderSum();
//                totalDiscountAmount += childOrder.getDiscountAmount();
//            }
//
//            //重新统计商品库存
//            productService.updateStock(productIdSet);
//


    @Override
    public R<Object> payOrder(Long mid, String orderCode, String ip) {
        if (mid == null || StringUtils.isBlank(orderCode)) {
            return R.fail("参数异常，无法支付");
        }
        Order order = baseMapper.selectOne(Wraps.<Order>lbQ().eq(Order::getOrderCode, orderCode));
        if (order == null) {
            return R.fail("订单不存在");
        }
        if (order.getOrderStatus() != OrderStatusEnum.NO_PAY.getCode() || order.getPayStatus() == PayStatusEnum.PAYED.getCode()) {
            return R.fail("订单状态不正确，无法支付");
        }
        Member member = memberService.findById(mid);
        Integer payChannel = order.getPayChannel();
        if (payChannel == 1) {
            WxPayAppOrderResult result = wxPay2(order.getOrderCode(), order.getOrderSum() - order.getDiscountAmount(), member.getOpenid(), ip, null);
            if (result.getPackageValue() != null) {
                order.setPrepayId(JSON.toJSONString(result));
                baseMapper.updateById(order);
            } else {
                return R.fail("支付失败");
            }
            return R.success(result);
        } else {
            AlipayTradeAppPayResponse result = aliPay(order.getOrderCode(), (order.getOrderSum() - order.getDiscountAmount()), member.getOpenid(), ip, JSON.toJSONString(order));
            if (result.getBody() != null) {
                order.setPrepayId(JSON.toJSONString(order.getOrderCode()));
                baseMapper.updateById(order);
            } else {
                return R.fail("下单失败");
            }
            return R.success(result);
        }
    }


    @Autowired
    private OrderProductService orderProductService;

    @Override
    public R<CountinuePayVo> continuePay(ContinuePayOrderDTO continuePayOrderDTO) {
        Long mid = continuePayOrderDTO.getMid();
        String orderCode = continuePayOrderDTO.getOrderCode();
        String ip = continuePayOrderDTO.getIp();


        Order order = baseMapper.selectOne(Wraps.<Order>lbQ().eq(Order::getOrderCode, orderCode).eq(Order::getMid, mid));

        Order order1 = baseMapper.selectById(order.getParentId());
        if (order == null) {
            return R.fail("订单不存在");
        }

        Member member = memberService.getById(mid);
        if (member == null) {
            return R.fail("用户信息有误，无法继续付款");
        }
        Object object = null;
        CountinuePayVo countinuePayVo = new CountinuePayVo();


        if (order1.getPayChannel() == 1) {
            object = wxPay2(order1.getOrderCode(), order1.getOrderSum() - order1.getDiscountAmount(), member.getOpenid(), ip, order1.getOrderCode());
            if (object == null) {
                return R.fail("继续付款失败");
            }
            order1.setPrepayId(JSON.toJSONString(object));
        } else {
            object = aliPay(order1.getOrderCode(), (order1.getOrderSum() - order1.getDiscountAmount()), member.getOpenid(), ip, order1.getOrderCode());
            if (object == null) {
                return R.fail("继续付款失败");
            }
            order1.setPrepayId(JSON.toJSONString(orderCode));
        }
        countinuePayVo.setObject(object);
        countinuePayVo.setPayChannel(order1.getPayChannel());
        baseMapper.updateById(order1);


        //埋点
        storeService.addStorePoint(order.getStoreId(), StoreDailyStatisticEnum.PAY);
        return R.success(countinuePayVo);
    }

    @Override
    public R<ReturnListVO> findReturnList(PageQueryDTO pageQueryDTO) {
        if (pageQueryDTO == null || pageQueryDTO.getMid() == null) {
            return R.fail(ExceptionCode.ILLEGALA_ARGUMENT_EX);
        }
        Long mid = pageQueryDTO.getMid();

        Integer returnMoneyCount = moneyReturnMapper.selectCount(Wraps.<MoneyReturn>lbQ().eq(MoneyReturn::getIsDelete, 0).eq(MoneyReturn::getMid, mid));
        Integer returnGoodsCount = goodsReturnMapper.selectCount(Wraps.<GoodsReturn>lbQ().eq(GoodsReturn::getIsDelete, 0).eq(GoodsReturn::getMid, mid));

        Integer total = returnMoneyCount + returnGoodsCount;

        pageQueryDTO.setStart((pageQueryDTO.getPageIndex() - 1) * pageQueryDTO.getPageSize());
        List<ReturnDTO> returnDTOList = baseMapper.selectReturnList(pageQueryDTO);
        List<ReturnVO> returnVOList = dozerUtils.mapList(returnDTOList, ReturnVO.class);
        for (ReturnVO returnVO : returnVOList) {
            Order order = baseMapper.selectById(returnVO.getOrderId());
            returnVO.setStoreId(order.getStoreId());
            returnVO.setStoreName(order.getStoreName());

            String opIds = returnVO.getOrderProductIds();
            if (StringUtils.isNoneBlank(opIds)) {
                List<Long> opIdList = new ArrayList<>();
                for (String opId : opIds.split(",")) {
                    opIdList.add(Long.valueOf(opId));
                }
                List<OrderProduct> orderProductList = orderProductMapper.selectList(Wraps.<OrderProduct>lbQ().in(OrderProduct::getId, opIdList).eq(OrderProduct::getIsDelete, 0));
                List<OrderProductVO> orderProductVOList = dozerUtils.mapList(orderProductList, OrderProductVO.class);
                returnVO.setOrderProductVOList(orderProductVOList);
            } else {
                List<OrderProduct> orderProductList = orderProductMapper.selectList(Wraps.<OrderProduct>lbQ().eq(OrderProduct::getOrderId, order.getId()).eq(OrderProduct::getIsDelete, 0));
                List<OrderProductVO> orderProductVOList = dozerUtils.mapList(orderProductList, OrderProductVO.class);
                returnVO.setOrderProductVOList(orderProductVOList);
            }
        }

        ReturnListVO returnListVO = new ReturnListVO();
        returnListVO.setTotal(total);
        returnListVO.setReturnVOList(returnVOList);

        return R.success(returnListVO);
    }

    @Override
    public R<Boolean> delOrder(Long mid, Long orderId) {
        if (mid == null || orderId == null) {
            return R.success(false);
        }
        baseMapper.delOrderById(mid, orderId);
        return R.success(true);
    }

    @Override
    public R<List<Order>> findChildOrderList(String orderCode) {
        if (orderCode == null) {
            return R.success(Collections.emptyList());
        }
        Order order = baseMapper.selectOne(Wraps.<Order>lbQ().eq(Order::getOrderCode, orderCode));
        if (order == null) {
            return R.success(Collections.emptyList());
        }
        //该订单为子订单
        if (order.getParentId() != 0) {
            return R.success(Arrays.asList(order));
        } else {//该订单为总订单
            List<Order> orderList = baseMapper.selectList(Wraps.<Order>lbQ().eq(Order::getParentId, order.getId()));
            return R.success(orderList);
        }
    }

    @Override
    public R<String> payOrderCallBack(PayOrderCallbackDTO payOrderCallbackDTO) {
        R<String> result = R.success("");
        if (payOrderCallbackDTO == null || StringUtils.isEmpty(payOrderCallbackDTO.getOrderCode())) {
            result.setCode(-1);
            result.setMsg("支付参数错误");
            return result;
        }
        Order payOrder = this.getOne(Wraps.<Order>lbQ().eq(Order::getOrderCode, payOrderCallbackDTO.getOrderCode()));

        payOrder.setPaySum(payOrder.getOrderSum() - payOrder.getDiscountAmount());
        payOrder.setPayTime(payOrderCallbackDTO.getPayTime());
        payOrder.setPayStatus(PayStatusEnum.PAYED.getCode());
        payOrder.setPayNum(payOrderCallbackDTO.getPayNum());
        payOrder.setOrderStatus(OrderStatusEnum.NO_SEND.getCode());

        this.updateById(payOrder);

        //按子订单付款
        if (payOrder.getParentId() == 0) {
            List<Order> childOrderList = this.list(Wraps.<Order>lbQ().eq(Order::getParentCode, payOrderCallbackDTO.getOrderCode()));
            for (int i = 0; i < childOrderList.size(); i++) {
                Order childOrderTmp = childOrderList.get(i);
                childOrderTmp.setPayStatus(PayStatusEnum.PAYED.getCode());
                childOrderTmp.setOrderStatus(payOrder.getOrderStatus());
                childOrderTmp.setPaySum(childOrderTmp.getOrderSum() - payOrder.getDiscountAmount());
                childOrderTmp.setPayTime(payOrder.getPayTime());
                childOrderTmp.setPayNum(payOrder.getPayNum());
                this.updateById(childOrderTmp);

                postProcessAfterOrderPay(childOrderTmp);

                //支付成功埋点
                storeService.addStorePoint(childOrderTmp.getStoreId(), StoreDailyStatisticEnum.PAY_SUCCESS);
            }
        } else {
            postProcessAfterOrderPay(payOrder);

            storeService
                    .addStorePoint(payOrder.getStoreId(), StoreDailyStatisticEnum.PAY_SUCCESS);
        }

        //发布订单支付事件
        orderEventUtil.publishOrderPaidEvent(payOrder);

        return R.success(payOrder.getOrderCode());
    }


    /**
     * 订单支付后的一些后置处理
     *
     * @param order
     */
    private void postProcessAfterOrderPay(Order order) {
        if (order.getParentId() == 0) {
            List<Order> childOrderList = this.list(Wraps.<Order>lbQ().eq(Order::getParentCode, order.getOrderCode()));
            for (int i = 0; i < childOrderList.size(); i++) {
                Order childOrder = childOrderList.get(i);
                if (childOrder.getPromotionId() != null && childOrder.getPromotionId() != 0) {
                    promotionStatService.payOrder(childOrder.getOrderCode());
                }
            }
        } else {
            if (order.getPromotionId() != null && order.getPromotionId() != 0) {
                promotionStatService.payOrder(order.getOrderCode());
            }
        }
    }

    @Override
    public R<OrderListVO> findOrderList(FindOrderListDTO findOrderListDTO) {
        //参数不能为空, 并且限制超过每页50个
        if (findOrderListDTO == null || findOrderListDTO.getMid() == null || findOrderListDTO.getPageSize() > 50) {
            return R.fail("参数错误");
        }
        //这里的订单状态，为前端页面的展示状态，和实际数据中的状态有点差别
        int orderStatus = findOrderListDTO.getOrderStatus();
        // 0-全部 1-待付款 2-待发货 3-待收货 4-已完成 其它值默认也是查全部
        List<Order> orderList = new ArrayList<Order>();
        Integer total = 0;

        OrderStatusEnum statusEnum = OrderStatusEnum.findByCode(orderStatus);
        total = baseMapper.findOrderListByStatusAndPageCount(findOrderListDTO.getMid(), statusEnum != null ? statusEnum.getCode() : null);
        orderList = baseMapper.findOrderListByStatusAndPage(findOrderListDTO.getMid(), statusEnum != null ? statusEnum.getCode() : null,
                (findOrderListDTO.getPageIndex() - 1) * findOrderListDTO.getPageSize(), findOrderListDTO.getPageSize());

        List<OrderVO> orderVOList = new ArrayList<>();

        for (Order order : orderList) {
            OrderVO orderVO = dozerUtils.map(order, OrderVO.class);
            orderVO.setId(order.getId());
            List<OrderProduct> orderProductList = orderProductMapper.selectList(Wraps.<OrderProduct>lbQ().eq(OrderProduct::getOrderId, order.getId()));
            List<OrderProductVO> orderProductVOList = dozerUtils.mapList(orderProductList, OrderProductVO.class);
            orderVO.setOrderProductVOList(orderProductVOList);

            //如果有退款单 或者 退货单，则查询出来
            Integer returnType = order.getReturnType();
            if (returnType != null) {
                if (returnType == ReturnTypeEnum.RETURN_MONEY.getCode()) {
                    List<MoneyReturn> moneyReturnList = moneyReturnMapper.selectList(Wraps.<MoneyReturn>lbQ().eq(MoneyReturn::getOrderId, order.getId()).eq(MoneyReturn::getCurrentVersion, 0));
                    orderVO.setMoneyReturnList(moneyReturnList);
                } else if (returnType == ReturnTypeEnum.RETURN_GOODS.getCode()) {
                    List<GoodsReturn> goodsReturnList = goodsReturnMapper.selectList(Wraps.<GoodsReturn>lbQ().eq(GoodsReturn::getOrderId, order.getId()).eq(GoodsReturn::getCurrentVersion, 0));
                    orderVO.setGoodsReturnList(goodsReturnList);
                }
            }
            if (orderVO.getOrderStatus() == OrderStatusEnum.NO_PAY.getCode()) {
                orderVO.setOverTime(order.getCreateTime().plusHours(2));
            }

            //如果订单已完成，并且距离完成时间10天之内，设置商品的评价状态
            for (OrderProductVO op : orderProductVOList) {
                //如果不是已完成，直接设置 忽略评价状态
                if (order.getOrderStatus() != OrderStatusEnum.FINISH.getCode()) {
                    op.setCommentStatus(CommentStatusEnum.NOT_STATUS.getCode());
                } else {
                    //代表这个订单距离下单日期已经超过15天了,目前超过15天是不允许再评价了
                    if (order.getCreateTime().plusDays(10).isBefore(LocalDateTime.now())) {
                        op.setCommentStatus(CommentStatusEnum.NOT_STATUS.getCode());
                    } else {
                        Comment comment = commentMapper.selectOne(Wraps.<Comment>lbQ().eq(Comment::getMid, findOrderListDTO.getMid()).eq(Comment::getOrderProductId, op.getId()).eq(Comment::getBizType, CommentTypeEnum.NORMAL.getCode()));
                        if (comment != null) {
                            op.setCommentStatus(CommentStatusEnum.COMMENTED.getCode());
                            Comment additionalComment = commentMapper.selectOne(Wraps.<Comment>lbQ().eq(Comment::getMid, findOrderListDTO.getMid())
                                    .eq(Comment::getParentId, comment.getId())
                                    .eq(Comment::getBizType, CommentTypeEnum.ADDITIONAL.getCode()));
                            op.setComment(comment);
                            op.setAdditionalComment(additionalComment);
                        } else {
                            op.setCommentStatus(CommentStatusEnum.WAITING_COMMENT.getCode());
                        }
                    }
                }
            }
            orderVOList.add(orderVO);
        }

        OrderListVO orderListVO = new OrderListVO();
        orderListVO.setTotal(total);
        orderListVO.setOrderVOList(orderVOList);

        return R.success(orderListVO);
    }

    @Override
    public R<MoneyReturnVO> applyReturnMoney(ApplyReturnMoneyDTO applyReturnMoneyDTO) {

        Long mid = applyReturnMoneyDTO.getMid();
        String orderCode = applyReturnMoneyDTO.getOrderCode();
        String orderProductIds = applyReturnMoneyDTO.getOrderProductIds();
        Integer goodsState = applyReturnMoneyDTO.getGoodsState();
        Long refundFee = applyReturnMoneyDTO.getRefundFee();
        Integer returnReason = applyReturnMoneyDTO.getReturnReason();
        String returnDesc = applyReturnMoneyDTO.getReturnDesc();
        String returnImgs = applyReturnMoneyDTO.getReturnImgs();

        Order order = this.getOne(Wraps.<Order>lbQ().eq(Order::getOrderCode, orderCode));
        if (order == null) {
            return R.fail("订单不存在");
        }

        if (!mid.equals(order.getMid())) {
            return R.fail("您没有权限对该订单进行退款操作");
        }
        if (order.getPayTime() == null) {
            return R.fail("订单错误");
        }
        if (!LocalDateTime.now().isBefore(order.getPayTime().plusDays(30))) {
            return R.fail("售后已经失效");
        }


        /*if(refundFee > order.getOrderSum()-order.getPostFee()){
            return R.fail("退款金额不能超过订单金额");
        }*/

        List<Long> orderProductIdList = new ArrayList<>();
        for (String orderProductId : orderProductIds.split(",")) {
            orderProductIdList.add(Long.valueOf(orderProductId));
        }

        MoneyReturn moneyReturn = new MoneyReturn();
        moneyReturn.setTenantCode(order.getTenantCode());
        moneyReturn.setMid(mid);
        moneyReturn.setOrderId(order.getId());
        moneyReturn.setOrderCode(orderCode);

        //针对单个orderProductId校验是否可以申请
        List<String> conflictList = new ArrayList<String>();

        Map<Long, OrderProduct> opMap = new HashMap<Long, OrderProduct>();
        List<OrderProduct> opList = orderProductMapper.selectBatchIds(orderProductIdList);
        StringBuilder opNameStrBuilder = new StringBuilder();
        Long canApplyAmount = 0L;
        for (OrderProduct op : opList) {
            opMap.put(op.getId(), op);
            opNameStrBuilder.append(op.getProductName() + " " + op.getSkuNameStr()).append(",");
            canApplyAmount += op.getBuyNum() * op.getSellPrice() - op.getDiscountAmount();
        }

//        if (refundFee > canApplyAmount) {
//            return R.fail("退款金额不能超过商品金额");
//        }

        for (Long orderProductId : orderProductIdList) {
            moneyReturn.setOrderProductIds(orderProductId.toString());
            Integer conflictCount = moneyReturnMapper.getConflictCount(moneyReturn);
            if (conflictCount > 0) {
                OrderProduct orderProduct = opMap.get(orderProductId);
                conflictList.add(orderProduct.getProductName() + "" + orderProduct.getSkuNameStr());
            }
        }
        if (conflictList.size() > 0) {
            return R.fail(-1, "以下商品已在售后中，不要重复申请，" + StringUtils.join(conflictList));
        }


        /**
         * 20201228
         * chenke
         * 查询商品是否是诺金商品  orderProductIdList
         */
        List<AdminProductVO> adminProductListByIds = productService.findAdminProductListByIds(orderProductIdList);
        int coinNum = 0;
        for (AdminProductVO adminProductListById : adminProductListByIds) {
//            if (adminProductListById.getProductType() == 2) {
//                coinNum = coinNum + 1;
//            }
        }

        if (coinNum >= 1 && coinNum != adminProductListByIds.size()) {
            return R.fail(-1, "普通商品和诺金商品不能一起申请");
        }

        moneyReturn.setOrderProductIds(orderProductIds);

        for (Long orderProductId : orderProductIdList) {
            moneyReturnMapper.increseVersionByOrderProductId(order.getId(), orderProductId);
        }

        //插入数据库
        moneyReturn.setGoodsState(goodsState);
        moneyReturn.setReturnCode(System.currentTimeMillis() + "");
        moneyReturn.setReturnReason(returnReason);
        moneyReturn.setReturnDesc(returnDesc);
        moneyReturn.setReturnImgs(returnImgs);
        moneyReturn.setStatus(ReturnMoneyStatusEnum.AUDITING.getCode());
        moneyReturn.setApplySum(refundFee);
        moneyReturn.setCreateTime(LocalDateTime.now());

        order.setReturnType(ReturnTypeEnum.RETURN_MONEY.getCode());

        MoneyReturnActionHistory moneyReturnActionHistory = new MoneyReturnActionHistory();
        moneyReturnActionHistory.setTenantCode(moneyReturn.getTenantCode());
        moneyReturnActionHistory.setOrderId(order.getId());
        moneyReturnActionHistory.setReturnCode(moneyReturn.getReturnCode());
        moneyReturnActionHistory.setStatus(moneyReturn.getStatus());
        if (coinNum == 0) {
            moneyReturnActionHistory.setActionNote("买家发起了仅退款申请, 退款商品: " + opNameStrBuilder.toString() + " 货物状态:" + GoodsStateEnum.findDescByCode(goodsState) + ", 原因:"
                    + ReturnMoneyReasonEnum.findDescByCode(returnReason) + ", 金额:" + transferMoney(refundFee) + "元");
        } else {
            moneyReturnActionHistory.setActionNote("买家发起了仅退款申请, 退款商品: " + opNameStrBuilder.toString() + " 货物状态:" + GoodsStateEnum.findDescByCode(goodsState) + ", 原因:"
                    + ReturnMoneyReasonEnum.findDescByCode(returnReason) + ", 金额:" + transferMoney(refundFee) + "诺金");
        }
        moneyReturnActionHistoryMapper.insert(moneyReturnActionHistory);

        this.updateById(order);

        moneyReturnMapper.insert(moneyReturn);


        return R.success(dozerUtils.map(moneyReturn, MoneyReturnVO.class));
    }

    @Override
    public R<Boolean> auditReturnMoney(AuditReturnMoneyDTO auditReturnMoneyDTO) {

        Long moneyReturnId = auditReturnMoneyDTO.getReturnMoneyId();
        Integer auditStatus = auditReturnMoneyDTO.getAuditStatus();
        String returnMoneyRemark = auditReturnMoneyDTO.getReturnMoneyRemark();

        if (moneyReturnId == null
                || !Arrays.asList(ReturnMoneyStatusEnum.AUDIT_PASS.getCode(), ReturnMoneyStatusEnum.AUDIT_REJECT.getCode()).contains(auditStatus)) {
            return R.fail("参数错误");
        }

        MoneyReturn moneyReturn = moneyReturnMapper.selectById(moneyReturnId);
        if (moneyReturn != null && moneyReturn.getStatus() == ReturnMoneyStatusEnum.AUDITING.getCode()) {
            moneyReturn.setStatus(auditStatus);
            moneyReturn.setReturnMoneyRemark(returnMoneyRemark);
            moneyReturn.setAuditTime(LocalDateTime.now());
            moneyReturnMapper.updateById(moneyReturn);

            String auditStr = "审核不通过";

            if (auditStatus == ReturnMoneyStatusEnum.AUDIT_PASS.getCode()) {
                auditStr = "审核通过";
                Long orderId = moneyReturn.getOrderId();
                Order childOrder = baseMapper.selectById(orderId);

                String outTradeNo = null;
                Integer totalFee = null;

                if (childOrder.getPrepayId() != null && StringUtils.isNotBlank(childOrder.getPrepayId())) {
                    outTradeNo = childOrder.getOrderCode();
                    totalFee = childOrder.getPaySum().intValue();
                } else {
                    Order parentOrder = baseMapper.selectByIdIgnoreTenant(childOrder.getParentId());
                    outTradeNo = parentOrder.getOrderCode();
                    totalFee = parentOrder.getPaySum().intValue();
                }

                WxPayRefundRequest req = new WxPayRefundRequest();
                req.setOutRefundNo(moneyReturn.getReturnCode());
                req.setOutTradeNo(outTradeNo);
                //订单总金额为支付的金额
                req.setTotalFee(totalFee);
                //只退订单的金额，不退运费
                req.setRefundFee(moneyReturn.getApplySum().intValue());

                AlipayTradeRefundApplyModel applyModel = new AlipayTradeRefundApplyModel();
                applyModel.setOutTradeNo(outTradeNo);
                applyModel.setOutRequestNo(String.valueOf(moneyReturn.getId()));
                // applyModel.setTradeNo();
                applyModel.setRefundAmount(String.valueOf(moneyReturn.getApplySum().intValue() * 1.0 / 100));
                applyModel.setRefundReason(moneyReturn.getReturnDesc());

                /**
                 * 20201218
                 * chenke
                 * 诺金支付，退款时，退诺金
                 *
                 */
                try {//微信支付的
                    if (childOrder.getPayChannel() == 1) {
                        payService.refund(req);
                    }
                    //支付宝支付的
                    else if (childOrder.getPayChannel() == 2) {
//                        AlipayTradeRefundResponse refund = payService.refund(applyModel);
//                        System.out.println(refund.isSuccess());
//                        System.out.println(refund.getBody());
                    }
                } catch (Exception e) {
                    log.error("refund fail:" + e.getMessage(), e);
                    return R.fail("后台申请退款失败");
                }
                List<Long> listIds = new ArrayList<>();
                String[] split = moneyReturn.getOrderProductIds().split(",");
                for (String s : split) {
                    listIds.add(Long.parseLong(s));
                }
            }

            MoneyReturnActionHistory moneyReturnActionHistory = new MoneyReturnActionHistory();
            moneyReturnActionHistory.setOrderId(moneyReturn.getOrderId());
            moneyReturnActionHistory.setReturnCode(moneyReturn.getReturnCode());
            moneyReturnActionHistory.setStatus(moneyReturn.getStatus());
            moneyReturnActionHistory.setActionNote("卖家审核退款申请, 审核状态:" + auditStr + ", 备注:" + returnMoneyRemark);
            moneyReturnActionHistoryMapper.insert(moneyReturnActionHistory);

        } else {
            return R.fail("退款单不存在或不是审核中状态");
        }

        return R.success();
    }

    @Override
    public R<Boolean> moneyReturnCallback(MoneyReturnCallbackDTO moneyReturnCallbackDTO) {

        //Integer returnType = moneyReturnCallbackDTO.getReturnType();
        //String orderCode = moneyReturnCallbackDTO.getOrderCode();
        String returnCode = moneyReturnCallbackDTO.getReturnCode();
        String thirdReturnNo = moneyReturnCallbackDTO.getThirdReturnNo();
        Long refundFee = moneyReturnCallbackDTO.getRefundFee();

        if (StringUtils.isEmpty(returnCode)) {
            return R.fail("参数错误");
        }

        try {

            MoneyReturn moneyReturn = moneyReturnMapper.selectOne(Wraps.<MoneyReturn>lbQ().eq(MoneyReturn::getReturnCode, returnCode).eq(MoneyReturn::getCurrentVersion, 0));

            if (moneyReturn != null) {
                moneyReturn.setStatus(ReturnMoneyStatusEnum.REFUND_SUC.getCode());
                moneyReturn.setRealReturnSum(moneyReturn.getApplySum());
                moneyReturn.setThirdReturnNo(thirdReturnNo);
                moneyReturn.setReturnTime(LocalDateTime.now());

                moneyReturnMapper.updateById(moneyReturn);

                //查询是否子订单下的商品都已退款
                List<MoneyReturn> refundSucMoneyReturnList = moneyReturnMapper.selectList(Wraps.<MoneyReturn>lbQ().eq(MoneyReturn::getOrderCode, moneyReturn.getOrderCode()).eq(MoneyReturn::getStatus, ReturnMoneyStatusEnum.REFUND_SUC.getCode()));

                int refundSucCount = 0;
                for (MoneyReturn refundSucMoneyReturn : refundSucMoneyReturnList) {
                    refundSucCount += refundSucMoneyReturn.getOrderProductIds().split(",").length;
                }

                //查询子订单
                Order childOrder = this.getOne(Wraps.<Order>lbQ().eq(Order::getOrderCode, moneyReturn.getOrderCode()));

                List<OrderProduct> orderProductList = orderProductMapper.selectList(Wraps.<OrderProduct>lbQ().eq(OrderProduct::getOrderId, childOrder.getId()));

                //如果子订单下的全部商品都退款成功，修改订单状态为已取消
                if (refundSucCount == orderProductList.size()) {
                    childOrder.setOrderStatus(OrderStatusEnum.CANCELED.getCode());
                    this.updateById(childOrder);
                }

                //更新退款成功的sku的库存
                for (String orderProductId : moneyReturn.getOrderProductIds().split(",")) {
                    for (OrderProduct orderProduct : orderProductList) {
                        if (orderProduct.getId().toString().equals(orderProductId)) {
                            productSkuService.updateSkuStock(orderProduct.getSkuId(), orderProduct.getBuyNum());
                            break;
                        }
                    }
                }

                /*for(OrderProduct orderProduct:orderProductList){
                    productSkuService.updateSkuStock(orderProduct.getSkuId(),orderProduct.getBuyNum());
                }*/

                MoneyReturnActionHistory moneyReturnActionHistory = new MoneyReturnActionHistory();
                moneyReturnActionHistory.setTenantCode(moneyReturn.getTenantCode());
                moneyReturnActionHistory.setReturnCode(moneyReturn.getReturnCode());
                moneyReturnActionHistory.setOrderId(moneyReturn.getOrderId());
                moneyReturnActionHistory.setStatus(moneyReturn.getStatus());
                moneyReturnActionHistory.setActionNote("卖家主动退款, 退款给买家" + transferMoney(refundFee) + "元");
                moneyReturnActionHistoryMapper.insert(moneyReturnActionHistory);

            } else {
                GoodsReturn goodsReturn = goodsReturnMapper.selectOne(Wraps.<GoodsReturn>lbQ().eq(GoodsReturn::getReturnCode, returnCode).eq(GoodsReturn::getReturnCode, returnCode));

                if (goodsReturn != null) {
                    goodsReturn.setStatus(ReturnGoodsStatusEnum.REFUND_SUC.getCode());
                    goodsReturn.setRealReturnSum(goodsReturn.getApplySum());
                    goodsReturn.setThirdReturnNo(thirdReturnNo);

                    goodsReturnMapper.updateById(goodsReturn);

                    //修改对应的子订单的状态
                    Order childOrder = this.getOne(Wraps.<Order>lbQ().eq(Order::getOrderCode, goodsReturn.getOrderCode()));

                    childOrder.setOrderStatus(OrderStatusEnum.CANCELED.getCode());
                    this.updateById(childOrder);

                    List<OrderProduct> orderProductList = orderProductMapper.selectList(Wraps.<OrderProduct>lbQ().eq(OrderProduct::getOrderId, childOrder.getId()));
                    for (OrderProduct orderProduct : orderProductList) {
                        productSkuService.updateSkuStock(orderProduct.getSkuId(), orderProduct.getBuyNum());
                    }

                    GoodsReturnActionHistory goodsReturnActionHistory = new GoodsReturnActionHistory();
                    goodsReturnActionHistory.setTenantCode(goodsReturn.getTenantCode());
                    goodsReturnActionHistory.setReturnCode(goodsReturn.getReturnCode());
                    goodsReturnActionHistory.setOrderId(goodsReturn.getOrderId());
                    goodsReturnActionHistory.setStatus(goodsReturn.getStatus());
                    goodsReturnActionHistory.setActionNote("卖家主动退款, 退款给买家" + transferMoney(refundFee) + "元");
                    goodsReturnActionHistoryMapper.insert(goodsReturnActionHistory);
                }
            }

        } catch (Exception e) {
            log.error("moneyReturnCallback fail: param={} message={}",
                    JSON.toJSONString(moneyReturnCallbackDTO), e.getMessage(), e);
            return R.fail("退款回调失败");
        }

        return R.success();
    }

    @Override
    public R<Boolean> sendGoods(SendGoodsDTO sendGoodsDTO) {

        if (sendGoodsDTO == null || StringUtils.isEmpty(sendGoodsDTO.getLogisticsName()) || StringUtils.isEmpty(sendGoodsDTO.getLogisticsNum())) {
            return R.fail("参数错误");
        }

        try {
            Order order = baseMapper.selectOne(Wraps.<Order>lbQ().eq(Order::getId, sendGoodsDTO.getOrderId()));

            if (order == null) {
                return R.fail("订单不存在");
            }

            if (order.getReturnType() == ReturnTypeEnum.RETURN_MONEY.getCode()) {
                List<MoneyReturn> moneyReturnList = moneyReturnMapper.selectList(Wraps.<MoneyReturn>lbQ().eq(MoneyReturn::getOrderId, order.getId())
                        .eq(MoneyReturn::getIsDelete, 0)
                        .orderByDesc(MoneyReturn::getCreateTime));
                if (moneyReturnList != null && moneyReturnList.size() > 0) {
                    MoneyReturn moneyReturn = moneyReturnList.get(0);
                    if (!ReturnMoneyStatusEnum.CAN_OPERATE_STATUS.contains(moneyReturn.getStatus())) {
                        return R.fail("当前有退款流程正在处理中, 无法发货");
                    }
                }
            }

            if (order.getReturnType() == ReturnTypeEnum.RETURN_GOODS.getCode()) {
                List<GoodsReturn> goodsReturnList = goodsReturnMapper.selectList(Wraps.<GoodsReturn>lbQ().eq(GoodsReturn::getOrderId, order.getId())
                        .eq(GoodsReturn::getIsDelete, 0)
                        .orderByDesc(GoodsReturn::getCreateTime));
                if (goodsReturnList != null && goodsReturnList.size() > 0) {
                    GoodsReturn goodsReturn = goodsReturnList.get(0);
                    if (!ReturnGoodsStatusEnum.CAN_OPERATE_STATUS.contains(goodsReturn.getStatus())) {
                        return R.fail("当前有退货流程正在处理中, 无法发货");
                    }
                }
            }

            if (order.getOrderStatus() != OrderStatusEnum.NO_SEND.getCode()) {
                return R.fail("订单状态不为待发货, 无法发货");
            }

            //设置订单状态为 待收货, 无退货流程
            order.setOrderStatus(OrderStatusEnum.NO_RECEIVE.getCode());

            //设置物流信息
            order.setLogisticsId(0L);
            order.setShipperCode(sendGoodsDTO.getShipperCode());
            order.setLogisticsName(sendGoodsDTO.getLogisticsName());
            order.setLogisticsNum(sendGoodsDTO.getLogisticsNum());

            //设置发货时间
            order.setSendTime(LocalDateTime.now());


            this.updateById(order);
            //设置推送快递信息
            subscribe(sendGoodsDTO.getLogisticsNum(), order.getRecMobile(), order.getShipperCode(), order.getId());
        } catch (Exception e) {
            log.error("sendGoods fail: sendGoodsDTO={}, errorMessage={}", JSON.toJSONString(sendGoodsDTO), e.getMessage(), e);
            return R.fail("发货失败");
        }

        return R.success();
    }

    /**
     * 推送快递接口
     *
     * @param logisticsNum 快递单号
     * @param recMobile    收件人手机号
     * @param shipperCode  快递编号
     * @throws Exception
     */
    public void subscribe(String logisticsNum, String recMobile, String shipperCode, Long orderId) throws Exception {
//        SubscribeParameters subscribeParameters = new SubscribeParameters();
//        subscribeParameters.setCallbackurl("http://api.shinuomall.com/app/order/expressSubscriptionCallbackInterface?orderId=" + orderId); //回调地址
//        subscribeParameters.setPhone(recMobile);
//
//        SubscribeParam subscribeParam = new SubscribeParam();
//        subscribeParam.setParameters(subscribeParameters);
//        subscribeParam.setCompany(shipperCode);
//        subscribeParam.setNumber(logisticsNum);
//        subscribeParam.setKey("TcWCEKLV2126");
//
//        SubscribeReq subscribeReq = new SubscribeReq();
//        subscribeReq.setSchema(ApiInfoConstant.SUBSCRIBE_SCHEMA);
//        subscribeReq.setParam(new Gson().toJson(subscribeParam));
//
//        IBaseClient subscribe = new Subscribe();
//
//        log.debug("快递100订阅推送发送结果|{}|订单号|{}", subscribeReq, orderId);

//        System.out.println(subscribe.execute(subscribeReq));
    }

    @Override
    public void expressSubscriptionCallbackInterface(HttpServletRequest request) {
//        String orderId = request.getParameter("orderId");
//        String param = request.getParameter("param");
//        //建议记录一下这个回调的内容，方便出问题后双方排查问题
//        log.debug("快递100订阅推送回调结果|{}|订单号|{}", param, orderId);
//
//        Order order = new Order();
//        order.setId(Long.valueOf(orderId));
//
//        //订阅时传的salt,没有可以忽略
//        SubscribePushParamResp subscribePushParamResp = new Gson().fromJson(param, SubscribePushParamResp.class);


    }

    @Override
    public R<GoodsReturnVO> applyReturnGoods(ApplyReturnGoodsDTO applyReturnGoodsDTO) {

        Long mid = applyReturnGoodsDTO.getMid();
        String orderCode = applyReturnGoodsDTO.getOrderCode();
        String orderProductIds = applyReturnGoodsDTO.getOrderProductIds();
        Integer returnType = applyReturnGoodsDTO.getReturnType();
        Long refundFee = applyReturnGoodsDTO.getRefundFee();
        Integer returnReason = applyReturnGoodsDTO.getReturnReason();
        String returnDesc = applyReturnGoodsDTO.getReturnDesc();
        String returnImgs = applyReturnGoodsDTO.getReturnImgs();

        Order order = this.getOne(Wraps.<Order>lbQ().eq(Order::getOrderCode, orderCode));

        /*OrderProduct orderProduct = orderProductMapper.selectById(orderProductId);
        if(order==null || orderProduct==null){
            throw new RuntimeException("订单或订单商品不存在");
        }*/

        if (!mid.equals(order.getMid())) {
            throw new RuntimeException("您没有权限对该订单进行退货操作");
        }
        if (BeanUtil.isEmpty(order.getPayTime())) {
            return R.fail("错误订单");
        }
        if (!LocalDateTime.now().isBefore(order.getPayTime().plusDays(30))) {
            return R.fail("售后已经失效");
        }
        /*if(!orderProduct.getOrderId().equals(order.getId())){
            throw new RuntimeException("订单与订单商品不对应");
        }*/

        List<Long> orderProductIdList = new ArrayList<>();
        for (String orderProductId : orderProductIds.split(",")) {
            orderProductIdList.add(Long.valueOf(orderProductId));
        }


        //以下的goodsReturn是为了 查询用户申请的goodsReturn是否已在退货中 或 已退货
        GoodsReturn goodsReturn = new GoodsReturn();
        goodsReturn.setTenantCode(order.getTenantCode());
        goodsReturn.setMid(mid);
        goodsReturn.setOrderId(order.getId());
        goodsReturn.setOrderCode(orderCode);
        goodsReturn.setOrderProductIds(orderProductIds);
        //goodsReturn.setProductId(orderProduct.getProductId());

        //针对单个orderProductId校验是否可以申请
        List<String> conflictList = new ArrayList<String>();

        Map<Long, OrderProduct> opMap = new HashMap<Long, OrderProduct>();
        List<OrderProduct> opList = orderProductMapper.selectBatchIds(orderProductIdList);
        StringBuilder opNameStrBuilder = new StringBuilder();
        Long canApplyAmount = 0L;
        for (OrderProduct op : opList) {
            opMap.put(op.getId(), op);
            opNameStrBuilder.append(op.getProductName() + " " + op.getSkuNameStr()).append(",");
            canApplyAmount += op.getBuyNum() * op.getSellPrice() - op.getDiscountAmount();
        }

//        if (refundFee > canApplyAmount) {
//            return R.fail("退款金额不能超过商品金额");
//        }

        for (Long orderProductId : orderProductIdList) {
            goodsReturn.setOrderProductIds(orderProductId.toString());
            Integer conflictCount = goodsReturnMapper.getConflictCount(goodsReturn);
            if (conflictCount > 0) {
                OrderProduct orderProduct = opMap.get(orderProductId);
                conflictList.add(orderProduct.getProductName() + "" + orderProduct.getSkuNameStr());
            }
        }
        if (conflictList.size() > 0) {
            return R.fail(-1, "以下商品已在售后中，不要重复申请，" + StringUtils.join(conflictList));
        }

        /**
         * 20201228
         * chenke
         * 查询商品是否是诺金商品  orderProductIdList
         */
        List<AdminProductVO> adminProductListByIds = productService.findAdminProductListByIds(orderProductIdList);
        int coinNum = 0;
        for (AdminProductVO adminProductListById : adminProductListByIds) {
//            if (adminProductListById.getProductType() == 2) {
//                coinNum = coinNum + 1;
//            }
        }

        if (coinNum >= 1 && coinNum != adminProductListByIds.size()) {
            return R.fail(-1, "普通商品和诺金商品不能一起申请");
        }

        goodsReturn.setOrderProductIds(orderProductIds);

        for (Long orderProductId : orderProductIdList) {
            goodsReturnMapper.increseVersionByOrderProductId(order.getId(), orderProductId);
        }

        //插入数据库
        goodsReturn.setReturnCode(System.currentTimeMillis() + "");
        goodsReturn.setReturnType(returnType);
        goodsReturn.setReturnReason(returnReason);
        goodsReturn.setReturnMoneyDesc(returnDesc);
        goodsReturn.setStatus(ReturnGoodsStatusEnum.AUDITING.getCode());
        goodsReturn.setApplySum(refundFee);
        goodsReturn.setApplyTime(LocalDateTime.now());
        goodsReturn.setReturnImgs(returnImgs);

        goodsReturnMapper.insert(goodsReturn);

        GoodsReturnActionHistory goodsReturnActionHistory = new GoodsReturnActionHistory();
        goodsReturnActionHistory.setTenantCode(order.getTenantCode());
        goodsReturnActionHistory.setReturnCode(goodsReturn.getReturnCode());
        goodsReturnActionHistory.setOrderId(order.getId());
        goodsReturnActionHistory.setStatus(goodsReturn.getStatus());
        String returnTypeStr = "上门取件";
        if (returnType == 2) {
            returnTypeStr = "商家同意退货后再决定";
        }
        if (coinNum == 0) {
            goodsReturnActionHistory.setActionNote("买家发起了退货退款申请, 退货商品: " + opNameStrBuilder.toString() + " 退货方式:" + returnTypeStr + ", 原因:"
                    + ReturnGoodsReasonEnum.findDescByCode(returnReason) + ", 金额:" + transferMoney(refundFee) + "元");
        } else {
            goodsReturnActionHistory.setActionNote("买家发起了退货退款申请, 退货商品: " + opNameStrBuilder.toString() + " 退货方式:" + returnTypeStr + ", 原因:"
                    + ReturnGoodsReasonEnum.findDescByCode(returnReason) + ", 金额:" + transferMoney(refundFee) + "诺金");
        }
        goodsReturnActionHistoryMapper.insert(goodsReturnActionHistory);

        //更新订单
        order.setReturnType(ReturnTypeEnum.RETURN_GOODS.getCode());
        this.updateById(order);


        return R.success(dozerUtils.map(goodsReturn, GoodsReturnVO.class));
    }

    @Override
    public R<Boolean> auditReturnGoods(AuditReturnGoodsDTO auditReturnGoodsDTO) {

        Long goodsReturnId = auditReturnGoodsDTO.getReturnGoodsId();
        Integer auditStatus = auditReturnGoodsDTO.getAuditStatus();
        String returnGoodsRemark = auditReturnGoodsDTO.getReturnGoodsRemark();

        if (goodsReturnId == null
                || !Arrays.asList(ReturnGoodsStatusEnum.AUDIT_PASS.getCode(), ReturnGoodsStatusEnum.AUDIT_REJECT.getCode()).contains(auditStatus)) {
            return R.fail("参数错误");
        }

        GoodsReturn goodsReturn = goodsReturnMapper.selectById(goodsReturnId);
        if (goodsReturn != null && goodsReturn.getStatus() == ReturnGoodsStatusEnum.AUDITING.getCode()) {
            goodsReturn.setStatus(auditStatus);
            goodsReturn.setReturnGoodsRemark(returnGoodsRemark);
            goodsReturnMapper.updateById(goodsReturn);

            GoodsReturnActionHistory goodsReturnActionHistory = new GoodsReturnActionHistory();
            goodsReturnActionHistory.setReturnCode(goodsReturn.getReturnCode());
            goodsReturnActionHistory.setOrderId(goodsReturn.getOrderId());
            goodsReturnActionHistory.setStatus(goodsReturn.getStatus());
            String auditStr = "审核通过";
            if (auditStatus == ReturnGoodsStatusEnum.AUDIT_REJECT.getCode()) {
                auditStr = "审核不通过";
            }
            goodsReturnActionHistory.setActionNote("卖家审核退货, 审核状态:" + auditStr + ", 备注:" + returnGoodsRemark);
            goodsReturnActionHistoryMapper.insert(goodsReturnActionHistory);

        } else {
            return R.fail("退货单不存在或不是审核中状态");
        }

        return R.success();

    }

    @Override
    public R<Boolean> sendReturnGoods(SendReturnGoodsDTO sendReturnGoodsDTO) {
        if (sendReturnGoodsDTO == null || sendReturnGoodsDTO.getGoodsReturnId() == null || sendReturnGoodsDTO.getMid() == null || sendReturnGoodsDTO.getLogisticsId() == null || sendReturnGoodsDTO.getLogisticsName() == null
                || sendReturnGoodsDTO.getLogisticsNum() == null || sendReturnGoodsDTO.getReturnImgs() == null) {
            return R.fail("参数错误");
        }

        GoodsReturn goodsReturn = goodsReturnMapper.selectById(sendReturnGoodsDTO.getGoodsReturnId());

        if (goodsReturn == null) {
            return R.fail("退货单不存在");
        }

        if (goodsReturn.getStatus() != ReturnGoodsStatusEnum.AUDIT_PASS.getCode()) {
            return R.fail("状态不正确，无法填写物流");
        }

        goodsReturn.setLogisticsId(sendReturnGoodsDTO.getLogisticsId());
        goodsReturn.setShipperCode(sendReturnGoodsDTO.getShipperCode());
        goodsReturn.setLogisticsName(sendReturnGoodsDTO.getLogisticsName());
        goodsReturn.setLogisticsNum(sendReturnGoodsDTO.getLogisticsNum());

        goodsReturn.setReturnGoodsDesc(sendReturnGoodsDTO.getReturnGoodsDesc());
        goodsReturn.setReturnGoodsTime(LocalDateTime.now());
        goodsReturn.setStatus(ReturnGoodsStatusEnum.GOODS_RETURNING.getCode());
        goodsReturn.setSendGoodsImgs(sendReturnGoodsDTO.getReturnImgs());

        goodsReturnMapper.updateById(goodsReturn);

        GoodsReturnActionHistory goodsReturnActionHistory = new GoodsReturnActionHistory();
        goodsReturnActionHistory.setTenantCode(goodsReturn.getTenantCode());
        goodsReturnActionHistory.setReturnCode(goodsReturn.getReturnCode());
        goodsReturnActionHistory.setOrderId(goodsReturn.getOrderId());
        goodsReturnActionHistory.setStatus(goodsReturn.getStatus());
        goodsReturnActionHistory.setActionNote("买家填写退货物流, 物流公司:" + sendReturnGoodsDTO.getLogisticsName() + ", 物流单号:" + sendReturnGoodsDTO.getLogisticsNum());
        goodsReturnActionHistoryMapper.insert(goodsReturnActionHistory);

        return R.success();
    }

    @Override
    public R<Boolean> confirmReturnGoods(ConfirmReturnGoodsDTO confirmReturnGoodsDTO) {

        if (confirmReturnGoodsDTO == null || confirmReturnGoodsDTO.getGoodsReturnId() == null || confirmReturnGoodsDTO.getConfirmStatus() == null
                || !Arrays.asList(ReturnGoodsStatusEnum.REFUNDING.getCode(), ReturnGoodsStatusEnum.REJECT_REFUND.getCode())
                .contains(confirmReturnGoodsDTO.getConfirmStatus())) {
            return R.fail("参数错误");
        }

        String returnMoneyRemark = confirmReturnGoodsDTO.getConfirmReturnGoodsDesc();

        GoodsReturn goodsReturn = goodsReturnMapper.selectById(confirmReturnGoodsDTO.getGoodsReturnId());
        if (goodsReturn == null) {
            return R.fail("退货单不存在");
        }
        if (goodsReturn.getStatus() != ReturnGoodsStatusEnum.GOODS_RETURNING.getCode()) {
            return R.fail("该退货单状态不是退货中，不能确认收货");
        }

        goodsReturn.setStatus(confirmReturnGoodsDTO.getConfirmStatus());
        goodsReturn.setAuditMoneyTime(LocalDateTime.now());

        goodsReturn.setReturnMoneyRemark(returnMoneyRemark);
        goodsReturn.setConfirmReturnGoodsDesc(confirmReturnGoodsDTO.getConfirmReturnGoodsDesc());

        if (confirmReturnGoodsDTO.getConfirmStatus() == ReturnGoodsStatusEnum.REFUNDING.getCode()) {
            Order childOrder = baseMapper.selectById(goodsReturn.getOrderId());

            String outTradeNo = null;
            Integer totalFee = null;

            if (childOrder.getPrepayId() != null && StringUtils.isNotBlank(childOrder.getPrepayId())) {
                outTradeNo = childOrder.getOrderCode();
                totalFee = childOrder.getOrderSum().intValue();
            } else {
                Order parentOrder = baseMapper.selectByIdIgnoreTenant(childOrder.getParentId());
                outTradeNo = parentOrder.getOrderCode();
                totalFee = parentOrder.getOrderSum().intValue();
            }


            WxPayRefundRequest req = new WxPayRefundRequest();
            req.setOutRefundNo(goodsReturn.getReturnCode());
            req.setOutTradeNo(outTradeNo);
            //订单总金额为支付的金额
            req.setTotalFee(totalFee);
            //只退订单的金额，不退运费
            req.setRefundFee(goodsReturn.getApplySum().intValue());
            AlipayTradeRefundApplyModel applyModel = new AlipayTradeRefundApplyModel();
            applyModel.setOutTradeNo(outTradeNo);
            applyModel.setOutRequestNo(String.valueOf(goodsReturn.getId()));
            // applyModel.setTradeNo();
            applyModel.setRefundAmount(String.valueOf(goodsReturn.getApplySum().intValue() * 1.0 / 100));

            try {
                /**
                 * 20201218
                 * chenke
                 * 增加不同的退款渠道：支付宝和微信
                 */
                if (childOrder.getPayChannel() == 1) {
                    payService.refund(req);
                }
                //支付宝支付的
                else if (childOrder.getPayChannel() == 2) {
//                    AlipayTradeRefundResponse refund = payService.refund(applyModel);
//                    System.out.println(refund.isSuccess());
//                    System.out.println(refund.getBody());
                }//诺金支付的
//                else {
//                    DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyyMMdd");
//                    String currentTime = LocalDateTime.now().format(fmt);
//                    Long mid = goodsReturn.getMid();
//                    MemberCoin coin = memberCoinService.getNlockCoin(mid).getData();
//                    //记录诺金
//                    coin.setLockCoin(coin.getLockCoin() == null ? 0l : coin.getLockCoin() + goodsReturn.getApplySum().intValue());
//                    MemberCoin tmp = new MemberCoin();
//                    BeanUtils.copyProperties(coin, tmp);
//                    memberCoinService.updateById(coin);
//                    MemberCoin after = memberCoinService.getNlockCoin(mid).getData();
//                    //记录诺金改变历史,退还诺金
//                    MemberCoinHis memberCoinHis = new MemberCoinHis();
//                    memberCoinHis.setCoinNum(goodsReturn.getApplySum().longValue());
//                    memberCoinHis.setMid(mid);
//                    memberCoinHis.setType(CoinTypeEnum.RetuenProduct_Coin.getCode());
//                    memberCoinHis.setBusiDate(currentTime);
//                    memberCoinHisService.save(memberCoinHis);
//                    memberCoinBaasEventUtil.publishMemberCoinBassEvent(tmp, new MemberCoin(), goodsReturn.getApplySum().longValue(), CoinTypeEnum.RetuenProduct_Coin.getCode());
//                }
                List<Long> listIds = new ArrayList<>();
                String[] split = goodsReturn.getOrderProductIds().split(",");
                for (String s : split) {
                    listIds.add(Long.parseLong(s));
                }
//                memberProfitOrderService.settleMemberReturnMoney(listIds);
//                R<Boolean> booleanR = salesProfitOrderService.settleSalesReturnMoney(listIds);
//                if (booleanR.getIsSuccess()) {
//
//                }

            } catch (Exception e) {
                log.error("confirmReturnGoods refund fail:" + e.getMessage(), e);
                return R.fail("后台确认收货, 申请退款失败");
            }
        }

        //商户确认收到退货之后，需要加回库存
        Long orderId = goodsReturn.getOrderId();
        List<OrderProduct> orderProductList = orderProductMapper.selectList(Wraps.<OrderProduct>lbQ().eq(OrderProduct::getOrderId, orderId));
        for (OrderProduct orderProduct : orderProductList) {
            productSkuService.updateSkuStock(orderProduct.getSkuId(), orderProduct.getBuyNum());
        }

        GoodsReturnActionHistory goodsReturnActionHistory = new GoodsReturnActionHistory();
        goodsReturnActionHistory.setReturnCode(goodsReturn.getReturnCode());
        goodsReturnActionHistory.setOrderId(goodsReturn.getOrderId());
        goodsReturnActionHistory.setStatus(goodsReturn.getStatus());
        String confirmStr = "卖家确认收到退货并同意退款";
        if (confirmReturnGoodsDTO.getConfirmStatus() == ReturnGoodsStatusEnum.REJECT_REFUND.getCode()) {
            confirmStr = "卖家确认收到退货并决绝退款";
        }
        goodsReturnActionHistory.setActionNote(confirmStr + ", 备注:" + returnMoneyRemark);
        goodsReturnActionHistoryMapper.insert(goodsReturnActionHistory);

        goodsReturnMapper.updateById(goodsReturn);

        return R.success();
    }

    @Override
    public R<SettlementVO> settlement(SettlementDTO settlementDTO) {

        if (settlementDTO == null || settlementDTO.getSkuItemDTOList() == null || settlementDTO.getSkuItemDTOList().size() == 0) {
            return R.fail("参数错误");
        }

        if (settlementDTO.getMid() == null || settlementDTO.getMid() <= 0L) {
            return R.fail("登录信息异常");
        }

        for (OrderSkuItemDTO skuItemDTO : settlementDTO.getSkuItemDTOList()) {
            if (skuItemDTO.getBuyNum() <= 0) {
                return R.fail("商品购买数量必须大于0");
            }
        }

        Map<Long, List<OrderProduct>> map = new HashMap<>();
        SettlementVO settlementVO = new SettlementVO();
        Set<Long> productIdSet = new HashSet<Long>();

        try {

            // 设置收货地址
            Long addressId = settlementDTO.getAddressId();
            if (addressId != null) {
                MemberAddress address = memberAddressService.getById(addressId);
                settlementVO.setMemberAddress(address);
            } else {
                MemberAddress defaultAddress = memberAddressService.queryDefaultAddress(settlementDTO.getMid());
                if (defaultAddress != null) {
                    settlementVO.setMemberAddress(defaultAddress);
                } else {
                    List<MemberAddress> addressList = memberAddressService.queryByMid(settlementDTO.getMid());
                    if (addressList != null && addressList.size() > 0) {
                        settlementVO.setMemberAddress(addressList.get(0));
                    }
                }
            }

            int index = 0;
            for (OrderSkuItemDTO skuDto : settlementDTO.getSkuItemDTOList()) {
                ProductSku productSku = productSkuService.getById(skuDto.getSkuId());
                TenantProduct product = productService.getByIdWithTenant(productSku.getProductId());
                Long storeId = product.getStoreId();
                if (map.get(storeId) == null) {
                    map.put(storeId, new ArrayList<>());
                }
                OrderProduct orderProduct = new OrderProduct();
                orderProduct.setProductId(product.getId());
                orderProduct.setSkuId(skuDto.getSkuId());
                orderProduct.setWeight(productSku.getWeight());
                orderProduct.setBuyNum(skuDto.getBuyNum());
                orderProduct.setApplyPrice(productSku.getApplyPrice());
                orderProduct.setSellPrice(productSku.getSkuPrice());
                orderProduct.setSkuNameStr(productSku.getSkuNameStr());
                orderProduct.setProductName(product.getProductName());
                orderProduct.setSkuImg(productSku.getSkuImg());
                orderProduct.setTenantCode(product.getTenantCode());
                orderProduct.setDiscountAmount(0L);

                productIdSet.add(product.getId());

                map.get(storeId).add(orderProduct);
                index++;
            }

            PromotionInfoDTO promotionInfoDTO = settlementDTO.getPromotionInfoDTO();

            //根据选择的活动计算优惠
            calcDiscountAmount(settlementDTO.getMid(), map, promotionInfoDTO, new HashMap<>());

            Long totalPostFee = 0L;
            Long totalCount = 0L;
            Long totalOrderSum = 0L;

            List<SettlementItemVO> settlementItemVOList = new ArrayList<SettlementItemVO>();
            for (Map.Entry<Long, List<OrderProduct>> entry : map.entrySet()) {
                //计算运费
                Long postFee = 0L;
                Long orderBuyCount = 0L;
                MemberAddress address = settlementVO.getMemberAddress();
                String tenantCode = entry.getValue().get(0).getTenantCode();
                if (address != null) {
                    String province = address.getProvince();
                    String city = address.getCity();
                    LogisticsCostDTO costDTO = logisticsService.getSuitableLogisticsCost(tenantCode, province, city, dozerUtils.mapList(entry.getValue(), OrderProductDTO.class));
                    if (costDTO != null) {
                        postFee = costDTO.getCost();
                    }
                }

                totalPostFee += postFee;

                List<OrderProduct> orderProductList = entry.getValue();
                SettlementItemVO settlementItemVO = new SettlementItemVO();
                settlementItemVO.setStoreId(entry.getKey());
                Store store = storeService.getById(entry.getKey());
                settlementItemVO.setStoreName(store.getStoreName());
                settlementItemVO.setOrderProductList(entry.getValue());
               // settlementItemVO.setStoreType(server.getStoreType());
                settlementItemVOList.add(settlementItemVO);

                //计算订单金额
                Long orderSum = 0L;
                for (OrderProduct orderProduct : entry.getValue()) {
                    orderBuyCount += Long.valueOf(orderProduct.getBuyNum());
                    orderSum += (orderProduct.getSellPrice() * orderProduct.getBuyNum() - orderProduct.getDiscountAmount());
                }

                //计算优惠
                if (promotionInfoDTO != null) {
                    List<PromotionDetailDTO> detailDTOList = new ArrayList<>();
                    Optional<List<PromotionDetailDTO>> optional = Optional.empty();

                    Long couponId = promotionInfoDTO.getCouponId();
                    if (couponId != null && couponId != 0) {
                        Coupon coupon = couponService.getById(couponId);
                        if (coupon == null || coupon.getIsDelete() == 1) {
                            return R.fail(-1, "优惠券不存在或已删除，不能使用");
                        }
                        if (coupon.getUseStartTime().isAfter(LocalDateTime.now())) {
                            return R.fail(-1, "优惠券还未到使用有效期");
                        }
                        if (coupon.getUseEndTime().isBefore(LocalDateTime.now())) {
                            return R.fail(-1, "优惠券已过期，不能使用");
                        }
                        PromotionDetailDTO detailDTO = new PromotionDetailDTO();
                        detailDTO.setFullAmount(coupon.getFullAmount());
                        detailDTO.setDiscountAmount(coupon.getDiscountAmount());
                        detailDTOList.add(detailDTO);
                        optional = Optional.of(detailDTOList);
                    }
                }

                totalCount += orderBuyCount;
                totalOrderSum += orderSum;

                settlementItemVO.setOrderSum(orderSum + postFee);
                settlementItemVO.setPostFee(postFee);
                settlementItemVO.setOrderBuyCount(orderBuyCount);
            }

            settlementVO.setMid(settlementDTO.getMid());
            settlementVO.setPostFee(totalPostFee);
            settlementVO.setTotalCount(totalCount);
            settlementVO.setOrderSum(totalOrderSum + totalPostFee);
            settlementVO.setSettlementItemVOList(settlementItemVOList);

            //查询商品关联的营销活动信息
            asemblePromotionInfo(settlementVO, productIdSet);

           // settlementVO.setIsBalance(false);


            //埋点
            storeService.addStorePoint(settlementItemVOList.stream().map(SettlementItemVO::getStoreId).collect(
                    Collectors.toList()), StoreDailyStatisticEnum.SETTLE);


        } catch (Exception e) {
            log.error("settlement fail: settlementDTO={}, errorMessage={}", JSON.toJSONString(settlementDTO), e.getMessage(), e);
            return R.fail("结算失败");
        }


        return R.success(settlementVO);
    }

    /**
     * 计算当前活动的优惠，并设置到每个购买的sku，并且返回整个订单的优惠价
     *
     * @param mid
     * @param opMap
     * @param promotionInfoDTO
     * @return
     */
    private Long calcDiscountAmount(Long mid, Map<Long, List<OrderProduct>> opMap,
                                    PromotionInfoDTO promotionInfoDTO, Map<Long, Boolean> matchMap) {
        if (promotionInfoDTO == null || promotionInfoDTO.getPromotionId() == null) {
            return 0L;
        }
        Long finalDiscountAmount = 0L;

        Set<Long> productIdSet = new HashSet<Long>();
        for (List<OrderProduct> opList : opMap.values()) {
            for (OrderProduct op : opList) {
                productIdSet.add(op.getProductId());
            }
        }

        matchMap = promotionService.matchPromotion(promotionInfoDTO.getPromotionId(), productIdSet);

        //本次购买参加当前活动的sku总价
        Long totalPromotionAmount = 0L;
        //总共有多少个sku参加当前活动
        Integer discountOpIndex = 0;
        for (List<OrderProduct> opList : opMap.values()) {
            for (OrderProduct op : opList) {
                if (matchMap.get(op.getProductId())) {
                    totalPromotionAmount += op.getBuyNum() * op.getSellPrice();
                    discountOpIndex += 1;
                }
            }
        }

        if (promotionInfoDTO != null && promotionInfoDTO.getPromotionId() != null) {

            Long promotionId = promotionInfoDTO.getPromotionId();
            Long couponId = promotionInfoDTO.getCouponId();

            if (couponId != null && couponId > 0) {
                Coupon coupon = couponService.getById(couponId);
                if (coupon != null && coupon.getIsDelete() == 0
                        && coupon.getUseStartTime().isBefore(LocalDateTime.now()) && coupon.getUseEndTime().isAfter(LocalDateTime.now())) {
                    finalDiscountAmount = coupon.getDiscountAmount();
                    //把优惠券标记为已使用
                    memberCouponService.useCoupon(mid, couponId);
                } else {
                    throw new RuntimeException("优惠券不存在或已失效");
                }
            } else {
                R<List<PromotionVO>> promotionVOListResult = promotionService.findPromotionList(mid, promotionInfoDTO.getPromotionId().toString());
                if (promotionVOListResult != null && promotionVOListResult.getCode() == 0) {
                    List<PromotionVO> promotionVOList = promotionVOListResult.getData();
                    if (promotionVOList != null && promotionVOList.size() > 0) {
                        PromotionVO promotionVO = promotionVOList.get(0);
                        //满减 叠加优惠
                        if (promotionVO.getPromotionType() == PromotionTypeEnum.FULL_DISCOUNT.getCode()
                                && promotionVO.getPromotionPlan() == PromotionPlanEnum.PLUS_DISCOUNT.getCode()) {
                            Map<String, Object> map = promotionVO.getPromotionDetail().get(0);
                            Long fullAmount = Long.valueOf(map.get("fullAmount").toString());
                            Long discountAmount = Long.valueOf(map.get("discountAmount").toString());
                            Long count = (totalPromotionAmount / fullAmount);
                            finalDiscountAmount = count * discountAmount;
                        } else if (promotionVO.getPromotionType() == PromotionTypeEnum.FULL_DISCOUNT.getCode()
                                && promotionVO.getPromotionPlan() == PromotionPlanEnum.LADDER_DISCOUNT.getCode()) {//满减阶梯优惠
                            List<Map<String, Object>> promotionDetailList = promotionVO.getPromotionDetail();
                            Collections.reverse(promotionDetailList);
                            for (Map<String, Object> map : promotionDetailList) {
                                Long fullAmount = Long.valueOf(map.get("fullAmount").toString());
                                Long discountAmount = Long.valueOf(map.get("discountAmount").toString());
                                if (totalPromotionAmount >= fullAmount) {
                                    finalDiscountAmount = discountAmount;
                                    break;
                                }
                            }
                        }
                    } else {
                        throw new RuntimeException("活动不存在或已结束");
                    }
                } else {
                    throw new RuntimeException("查询活动失败");
                }
            }
        }

        Long remainDiscountAmount = finalDiscountAmount;
        for (Map.Entry<Long, List<OrderProduct>> entry : opMap.entrySet()) {
            List<OrderProduct> orderProductList = entry.getValue();
            for (OrderProduct op : orderProductList) {
                Boolean matched = matchMap.get(op.getProductId());
                if (matched == null) {
                    matched = false;
                }
                if (matched) {
                    discountOpIndex--;
                    if (discountOpIndex == 0) {
                        op.setDiscountAmount(remainDiscountAmount);
                    } else {
                        Double discountPercent = ((op.getBuyNum() * op.getSellPrice()) / 1.0 / totalPromotionAmount);
                        op.setDiscountAmount(new BigDecimal(discountPercent * finalDiscountAmount).setScale(0, BigDecimal.ROUND_HALF_UP).longValue());
                    }
                    remainDiscountAmount = remainDiscountAmount - op.getDiscountAmount();
                } else {
                    op.setDiscountAmount(0L);
                }
            }
        }

        return finalDiscountAmount;
    }

    /**
     * 查询商品关联的营销活动信息
     *
     * @param settlementVO
     * @param productIdSet
     */
    private void asemblePromotionInfo(SettlementVO settlementVO, Set<Long> productIdSet) {
        Long mid = settlementVO.getMid();

        List<SettlementItemVO> settlementItemVOList = settlementVO.getSettlementItemVOList();
        //每个商品，及其对应的下单金额
        Map<Long, Long> productSumMap = new HashMap<Long, Long>();
        for (SettlementItemVO settlementItemVO : settlementItemVOList) {
            for (OrderProduct orderProduct : settlementItemVO.getOrderProductList()) {
                Long productId = orderProduct.getProductId();
                if (productSumMap.get(productId) == null) {
                    productSumMap.put(productId, 0L);
                }
                productSumMap.put(productId, productSumMap.get(productId) + (orderProduct.getSellPrice() * orderProduct.getBuyNum()));
            }
        }

        Map<Long, List<PromotionVO>> productPromotionMap = promotionService.findPromotionDetail(mid, productIdSet);

        SettlementPromotionVO settlementPromotionVO = new SettlementPromotionVO();
        if (productPromotionMap.size() > 0) {
            Map<Long, PromotionVO> promotionMap = new HashMap<Long, PromotionVO>();
            //计算每个活动下的商品购买了多少钱
            Map<Long, Long> promotionSumMap = new HashMap<Long, Long>();
            for (Map.Entry<Long, List<PromotionVO>> entry : productPromotionMap.entrySet()) {
                Long productId = entry.getKey();
                List<PromotionVO> promotionVOList = entry.getValue();
                if (promotionVOList != null && promotionVOList.size() > 0) {
                    for (PromotionVO promotionVO : promotionVOList) {
                        Long promotionId = promotionVO.getId();
                        promotionMap.put(promotionId, promotionVO);
                        if (promotionSumMap.get(promotionId) == null) {
                            promotionSumMap.put(promotionId, 0L);
                        }
                        Long productSum = productSumMap.get(productId);
                        Long originSum = promotionSumMap.get(promotionId);
                        promotionSumMap.put(promotionVO.getId(), originSum + productSum);
                    }
                }
            }

            List<SettlementPromotionItemVO> usableItemVOList = new ArrayList<>();
            List<SettlementPromotionItemVO> unusableItemVOList = new ArrayList<>();
            for (PromotionVO promotionVO : promotionMap.values()) {
                Long promotionSum = promotionSumMap.get(promotionVO.getId());
                if (promotionVO.getPromotionType() == PromotionTypeEnum.FULL_DISCOUNT.getCode()) {
                    //每满X减Y
                    if (promotionVO.getPromotionPlan() == PromotionPlanEnum.PLUS_DISCOUNT.getCode()) {
                        SettlementPromotionItemVO itemVO = new SettlementPromotionItemVO();
                        itemVO.setPromotionId(promotionVO.getId());
                        List<Map<String, Object>> promotionDetailList = promotionVO.getPromotionDetail();
                        if (promotionDetailList != null && promotionDetailList.size() > 0) {
                            itemVO.setPromotionPlan(promotionVO.getPromotionPlan());
                            itemVO.setFullAmount(Long.valueOf(promotionDetailList.get(0).get("fullAmount").toString()));
                            itemVO.setDiscountAmount(Long.valueOf(promotionDetailList.get(0).get("discountAmount").toString()));
                            itemVO.setStartTime(promotionVO.getActivityStartTime());
                            itemVO.setEndTime(promotionVO.getActivityEndTime());
                            if (promotionSum >= itemVO.getFullAmount()) {
                                usableItemVOList.add(itemVO);
                            } else {
                                unusableItemVOList.add(itemVO);
                            }
                        }
                    }
                    //阶梯优惠
                    if (promotionVO.getPromotionPlan() == PromotionPlanEnum.LADDER_DISCOUNT.getCode()) {
                        List<Map<String, Object>> promotionDetailList = promotionVO.getPromotionDetail();
                        if (promotionDetailList != null && promotionDetailList.size() > 0) {
                            Collections.reverse(promotionDetailList);
                            boolean addFlag = false;
                            for (Map<String, Object> map : promotionDetailList) {
                                SettlementPromotionItemVO itemVO = new SettlementPromotionItemVO();
                                itemVO.setPromotionId(promotionVO.getId());
                                itemVO.setPromotionPlan(promotionVO.getPromotionPlan());
                                itemVO.setFullAmount(Long.valueOf(map.get("fullAmount").toString()));
                                itemVO.setDiscountAmount(Long.valueOf(map.get("discountAmount").toString()));
                                itemVO.setStartTime(promotionVO.getActivityStartTime());
                                itemVO.setEndTime(promotionVO.getActivityEndTime());
                                if (promotionSum >= itemVO.getFullAmount() && !addFlag) {
                                    usableItemVOList.add(itemVO);
                                    addFlag = true;
                                }
                            }
                        }
                    }
                } else {
                    List<CouponVO> couponVOList = promotionVO.getCouponVOList();
                    for (CouponVO couponVO : couponVOList) {
                        SettlementPromotionItemVO itemVO = new SettlementPromotionItemVO();
                        itemVO.setPromotionId(promotionVO.getId());
                        itemVO.setPromotionPlan(promotionVO.getPromotionPlan());
                        itemVO.setFullAmount(couponVO.getFullAmount());
                        itemVO.setDiscountAmount(couponVO.getDiscountAmount());
                        itemVO.setIsCoupon(1);
                        itemVO.setCouponId(couponVO.getId());
                        itemVO.setReceived(couponVO.getReceived());
                        itemVO.setStartTime(couponVO.getUseStartTime());
                        itemVO.setEndTime(couponVO.getUseEndTime());
                        if (promotionSum >= couponVO.getFullAmount()) {
                            usableItemVOList.add(itemVO);
                        } else {
                            unusableItemVOList.add(itemVO);
                        }
                    }
                }
            }

            Collections.sort(usableItemVOList, new Comparator<SettlementPromotionItemVO>() {

                @Override
                public int compare(SettlementPromotionItemVO o1, SettlementPromotionItemVO o2) {
                    return Long.compare(o2.getDiscountAmount(), o1.getDiscountAmount());
                }
            });
            settlementPromotionVO.setUsableList(usableItemVOList);
            settlementPromotionVO.setUnusableList(unusableItemVOList);
        }
        settlementVO.setSettlementPromotionVO(settlementPromotionVO);
    }

    @Override
    public R<Boolean> cancelRefund(Long mid, Long moneyReturnId) {

        if (mid == null || moneyReturnId == null) {
            return R.fail("参数异常");
        }

        MoneyReturn moneyReturn = moneyReturnMapper.selectById(moneyReturnId);
        if (moneyReturn == null) {
            return R.fail("退款单不存在");
        }

        if (moneyReturn.getStatus() == ReturnMoneyStatusEnum.REFUND_SUC.getCode()) {
            return R.fail("该退款单已退款成功，不能取消退款");
        }

        if (moneyReturn.getStatus() == ReturnMoneyStatusEnum.REFUNDING.getCode()) {
            return R.fail("该退款单已在退款中，不能取消退款");
        }

        moneyReturn.setStatus(ReturnMoneyStatusEnum.CANCELED.getCode());
        moneyReturnMapper.updateById(moneyReturn);

        Order order = baseMapper.selectById(moneyReturn.getOrderId());
        if (order != null) {
            order.setReturnType(ReturnTypeEnum.NO_RETURN.getCode());
            this.updateById(order);
        }

        MoneyReturnActionHistory moneyReturnActionHistory = new MoneyReturnActionHistory();
        moneyReturnActionHistory.setTenantCode(moneyReturn.getTenantCode());
        moneyReturnActionHistory.setReturnCode(moneyReturn.getReturnCode());
        moneyReturnActionHistory.setOrderId(moneyReturn.getOrderId());
        moneyReturnActionHistory.setStatus(moneyReturn.getStatus());
        moneyReturnActionHistory.setActionNote("买家主动撤销退款");
        moneyReturnActionHistoryMapper.insert(moneyReturnActionHistory);

        return R.success();
    }

    @Override
    public R<Boolean> cancelReturnGoods(Long mid, Long goodsReturnId) {
        if (mid == null || goodsReturnId == null) {
            return R.fail("参数异常");
        }
        GoodsReturn goodsReturn = goodsReturnMapper.selectById(goodsReturnId);
        if (goodsReturn == null) {
            return R.fail("退货单不存在");
        }
        if (goodsReturn.getStatus() == ReturnGoodsStatusEnum.GOODS_RETURN_SUC.getCode()) {
            return R.fail("该退货单已退回货物，待退款，不能撤销申请");
        }
        if (goodsReturn.getStatus() == ReturnGoodsStatusEnum.REJECT_REFUND.getCode()) {
            return R.fail("该退货单已退回货物，被商户拒绝退款，不能撤销申请");
        }
        if (goodsReturn.getStatus() == ReturnGoodsStatusEnum.GOODS_RETURNING.getCode()) {
            return R.fail("该退货单已在退货中，不能撤销申请");
        }
        if (goodsReturn.getStatus() == ReturnGoodsStatusEnum.REFUND_SUC.getCode()) {
            return R.fail("该退货单已退款成功，不能撤销申请");
        }
        if (goodsReturn.getStatus() == ReturnGoodsStatusEnum.REFUNDING.getCode()) {
            return R.fail("该退货单已在退款中，不能撤销申请");
        }
        goodsReturn.setStatus(ReturnGoodsStatusEnum.CANCELED.getCode());
        goodsReturnMapper.updateById(goodsReturn);

        Order order = baseMapper.selectById(goodsReturn.getOrderId());
        if (order != null) {
            order.setReturnType(ReturnTypeEnum.NO_RETURN.getCode());
            this.updateById(order);
        }
        return R.success();
    }

    @Override
    public R<Boolean> cancelOrder(Long mid, Long orderId) {

        if (mid == null || orderId == null) {
            return R.fail("参数异常");
        }

        Order order = baseMapper.selectById(orderId);
        if (order == null) {
            return R.fail("订单不存在");
        }
        if (!mid.equals(order.getMid())) {
            return R.fail("无权操作该订单");
        }
        if (order.getOrderStatus() != OrderStatusEnum.NO_PAY.getCode()) {
            return R.fail("只有待付款的订单才能取消");
        }
        order.setOrderStatus(OrderStatusEnum.CANCELED.getCode());
        baseMapper.updateById(order);

        List<OrderProduct> orderProductList = orderProductMapper.selectList(Wraps.<OrderProduct>lbQ().eq(OrderProduct::getOrderId, order.getId()));
        for (OrderProduct orderProduct : orderProductList) {
            productSkuService.updateSkuStock(orderProduct.getSkuId(), orderProduct.getBuyNum());
        }

        //发布订单取消事件
        orderEventUtil.publishOrderCancelEvent(order);

        return R.success();
    }

    @Override
    public R<Boolean> confirmReceiveGooods(Long mid, Long orderId) {
        if (mid == null || orderId == null) {
            return R.fail("参数错误");
        }
        Order order = baseMapper.selectById(orderId);
        if (order == null) {
            return R.fail("订单不存在");
        }
        if (!mid.equals(order.getMid())) {
            return R.fail("无权操作该订单");
        }
        if (order.getReturnType() == ReturnTypeEnum.RETURN_MONEY.getCode()) {
            List<MoneyReturn> moneyReturnList = moneyReturnMapper.selectList(Wraps.<MoneyReturn>lbQ().eq(MoneyReturn::getOrderId, order.getId())
                    .eq(MoneyReturn::getIsDelete, 0)
                    .orderByDesc(MoneyReturn::getCreateTime));
            if (moneyReturnList != null && moneyReturnList.size() > 0) {
                MoneyReturn moneyReturn = moneyReturnList.get(0);
                if (!ReturnMoneyStatusEnum.CAN_OPERATE_STATUS.contains(moneyReturn.getStatus())) {
                    return R.fail("当前有退款流程正在处理中, 无法确认收货");
                }
            }
        }

        if (order.getReturnType() == ReturnTypeEnum.RETURN_GOODS.getCode()) {
            List<GoodsReturn> goodsReturnList = goodsReturnMapper.selectList(Wraps.<GoodsReturn>lbQ().eq(GoodsReturn::getOrderId, order.getId())
                    .eq(GoodsReturn::getIsDelete, 0)
                    .orderByDesc(GoodsReturn::getCreateTime));
            if (goodsReturnList != null && goodsReturnList.size() > 0) {
                GoodsReturn goodsReturn = goodsReturnList.get(0);
                if (!ReturnGoodsStatusEnum.CAN_OPERATE_STATUS.contains(goodsReturn.getStatus())) {
                    return R.fail("当前有退货流程正在处理中, 无法确认收货");
                }
            }
        }
        if (order.getOrderStatus() != OrderStatusEnum.NO_RECEIVE.getCode()) {
            return R.fail("该订单不是待收货订单，不能确认收货");
        }
        order.setConfirmTime(LocalDateTime.now());
        order.setOrderStatus(OrderStatusEnum.FINISH.getCode());


        baseMapper.updateById(order);


        //更新

//        List<OrderProduct> orderProducts = orderProductMapper.selectByOrderId(order.getId());
//        List<Long> listIds = new ArrayList<>();
//        for (OrderProduct orderProduct : orderProducts) {
//            listIds.add(orderProduct.getId());
//        }
//
//
//            memberProfitOrderService.settleMemberOrder(listIds);
//        R<Boolean> booleanR = salesProfitOrderService.settleSalesrOrder(listIds);
//
//        orderEventUtil.publishOrderFinishEvent(order);
//        orderBassEventUtil.publishOrderBassEvent(order, OrderBassTriggerStatusEnum.STATUS_1.getCode());
//        if (booleanR.getIsSuccess()) {
//            orderBassEventUtil.publishOrderBassEvent(order, OrderBassTriggerStatusEnum.STATUS_2.getCode());
//        }


        return R.success();
    }

    @Override
    public R<OrderDetailVO> getOrderDetail(Long mid, Long orderId) {
        if (mid == null || orderId == null) {
            return R.fail("参数错误");
        }

        Order order = this.getById(orderId);
        if (order == null) {
            return R.fail("订单不存在");
        }
        if (!mid.equals(order.getMid())) {
            return R.fail("你无权查看该订单");
        }
        OrderStatusEnum statusEnum = OrderStatusEnum.findByCode(order.getOrderStatus());
        if (statusEnum == null) {
            return R.fail("订单状态异常");
        }

        OrderDetailVO orderDetailVO = new OrderDetailVO();

        orderDetailVO = dozerUtils.map(order, OrderDetailVO.class);
        orderDetailVO.setId(order.getId());
        List<OrderProduct> orderProductList = null;
        if (order.getParentId() != 0) {
            orderProductList = orderProductMapper.selectList(Wraps.<OrderProduct>lbQ().eq(OrderProduct::getOrderId, order.getId()));
        } else {
          //  orderProductList = orderProductMapper.selectByParentId(orderId);
        }
        orderDetailVO.setOrderProductVOList(dozerUtils.mapList(orderProductList, OrderProductVO.class));

        Map<Long, OrderProductVO> opVOMap = new HashMap<>();
        for (OrderProductVO opVO : orderDetailVO.getOrderProductVOList()) {
            opVOMap.put(opVO.getId(), opVO);
        }

        //有退款流程
        if (order.getReturnType() == ReturnTypeEnum.RETURN_MONEY.getCode()) {
            List<MoneyReturn> moneyReturnList = moneyReturnMapper.selectList(Wraps.<MoneyReturn>lbQ().eq(MoneyReturn::getOrderId, order.getId())
                    .eq(MoneyReturn::getIsDelete, 0)
                    .eq(MoneyReturn::getCurrentVersion, 0)
                    .orderByDesc(MoneyReturn::getCreateTime));
            orderDetailVO.setMoneyReturnVOList(dozerUtils.mapList(moneyReturnList, MoneyReturnVO.class));
            for (MoneyReturnVO mrv : orderDetailVO.getMoneyReturnVOList()) {
                List<ReturnIntervention> riList = returnInventionMapper.selectList(Wraps.<ReturnIntervention>lbQ().eq(ReturnIntervention::getReturnCode, mrv.getReturnCode()));
                if (riList.size() != 0) {
                    mrv.setReturnIntervention(riList.get(0));
                }
            }
            orderDetailVO.setMoneyReturnActionHistoryList(new ArrayList<>());
            for (MoneyReturnVO moneyReturnVO : orderDetailVO.getMoneyReturnVOList()) {
                int auditRejectCount = 0;
                List<MoneyReturnActionHistory> moneyReturnActionHistoryList = moneyReturnActionHistoryMapper.selectList(Wraps.<MoneyReturnActionHistory>lbQ().eq(MoneyReturnActionHistory::getOrderId, moneyReturnVO.getOrderId())
                        .eq(MoneyReturnActionHistory::getIsDelete, 0)
                        .orderByDesc(MoneyReturnActionHistory::getCreateTime));
                orderDetailVO.getMoneyReturnActionHistoryList().addAll(moneyReturnActionHistoryList);
                for (MoneyReturnActionHistory ah : moneyReturnActionHistoryList) {
                    if (ah.getStatus() == ReturnMoneyStatusEnum.AUDIT_REJECT.getCode()) {
                        auditRejectCount++;
                    }
                }
                if (auditRejectCount >= 2 && moneyReturnVO.getReturnIntervention() == null) {
                    moneyReturnVO.setCanApplyIntervention(1);
                }
                for (String opId : moneyReturnVO.getOrderProductIds().split(",")) {
                    OrderProductVO opVO = opVOMap.get(Long.valueOf(opId));
                    if (opVO != null) {
                        opVO.setReturnType(ReturnTypeEnum.RETURN_MONEY.getCode());
                        opVO.setReturnStatus(moneyReturnVO.getStatus());
                        opVO.setCanApplyIntervention(moneyReturnVO.getCanApplyIntervention());
                        opVO.setReturnCode(moneyReturnVO.getReturnCode());
                    }
                }
            }
        }
        //有退货流程
        if (order.getReturnType() == ReturnTypeEnum.RETURN_GOODS.getCode()) {
            List<GoodsReturn> goodsReturnList = goodsReturnMapper.selectList(Wraps.<GoodsReturn>lbQ().eq(GoodsReturn::getOrderId, order.getId())
                    .eq(GoodsReturn::getIsDelete, 0)
                    .eq(GoodsReturn::getCurrentVersion, 0)
                    .orderByDesc(GoodsReturn::getCreateTime));
            orderDetailVO.setGoodsReturnVOList(dozerUtils.mapList(goodsReturnList, GoodsReturnVO.class));
            for (GoodsReturnVO grv : orderDetailVO.getGoodsReturnVOList()) {
                List<ReturnIntervention> riList = returnInventionMapper.selectList(Wraps.<ReturnIntervention>lbQ().eq(ReturnIntervention::getReturnCode, grv.getReturnCode()));
                if (riList.size() != 0) {
                    grv.setReturnIntervention(riList.get(0));
                }
            }
            orderDetailVO.setGoodsReturnActionHistoryList(new ArrayList<>());
            for (GoodsReturnVO goodsReturnVO : orderDetailVO.getGoodsReturnVOList()) {
                int auditRejectCount = 0;
                List<GoodsReturnActionHistory> goodsReturnActionHistoryList = goodsReturnActionHistoryMapper.selectList(Wraps.<GoodsReturnActionHistory>lbQ().eq(GoodsReturnActionHistory::getOrderId, goodsReturnVO.getOrderId())
                        .eq(GoodsReturnActionHistory::getIsDelete, 0)
                        .orderByDesc(GoodsReturnActionHistory::getCreateTime));
                orderDetailVO.getGoodsReturnActionHistoryList().addAll(goodsReturnActionHistoryList);
                for (GoodsReturnActionHistory ah : goodsReturnActionHistoryList) {
                    if (ah.getStatus() == ReturnGoodsStatusEnum.AUDIT_REJECT.getCode()) {
                        auditRejectCount++;
                    }
                }
                if (auditRejectCount >= 2 && goodsReturnVO.getReturnIntervention() == null) {
                    goodsReturnVO.setCanApplyIntervention(1);
                }
                for (String opId : goodsReturnVO.getOrderProductIds().split(",")) {
                    OrderProductVO opVO = opVOMap.get(Long.valueOf(opId));
                    if (opVO != null) {
                        opVO.setReturnType(ReturnTypeEnum.RETURN_MONEY.getCode());
                        opVO.setReturnStatus(goodsReturnVO.getStatus());
                        opVO.setCanApplyIntervention(goodsReturnVO.getCanApplyIntervention());
                        opVO.setReturnCode(goodsReturnVO.getReturnCode());
                    }
                }
            }
        }

        //设置当前时间
        orderDetailVO.setCurrentTime(LocalDateTime.now());

        //如果是待付款，计算超时时间
        if (orderDetailVO.getOrderStatus() == OrderStatusEnum.NO_PAY.getCode()) {
            orderDetailVO.setOverTime(orderDetailVO.getCreateTime().plusHours(2));
        }
        LocalDateTime payTime = orderDetailVO.getPayTime();
      //  orderDetailVO.setIsGoodsReturn(false);
        if (payTime != null) {
            if (!LocalDateTime.now().isBefore(payTime.plusDays(30))) {
          //      orderDetailVO.setIsGoodsReturn(true);
            }
        }
        return R.success(orderDetailVO);
    }

    @Override
    public R<AdminOrderListDTO> findAdminOrderList(AdminOrderSearchParamDTO adminOrderSearchParamDTO) {
        Integer pageIndex = adminOrderSearchParamDTO.getPageIndex();
        Integer pageSize = adminOrderSearchParamDTO.getPageSize();
        Integer start = (pageIndex - 1) * pageSize;
        adminOrderSearchParamDTO.setStart(start);

        try {
            Integer total = baseMapper.searchAdminOrderListCount(adminOrderSearchParamDTO);
            List<AdminOrderDTO> adminOrderDTOList = baseMapper.searchAdminOrderList(adminOrderSearchParamDTO);
//            for (AdminOrderDTO adminOrderDTO : adminOrderDTOList) {
//                Integer productCount = orderProductMapper.selectCount(Wraps.<OrderProduct>lbQ().eq(OrderProduct::getOrderId, adminOrderDTO.getId()));
//                adminOrderDTO.setProductCount(productCount);
//                adminOrderDTO.setOrderProductList(orderProductMapper.queryProductList(adminOrderDTO.getOrderCode()));
//                adminOrderDTO.setCreateTimee(Date.from(adminOrderDTO.getCreateTime().atZone(ZoneId.systemDefault()).toInstant()));
//            }
            AdminOrderListDTO orderListDTO = new AdminOrderListDTO();
            orderListDTO.setTotal(total);
            orderListDTO.setAdminOrderDTOList(adminOrderDTOList);
            return R.success(orderListDTO);
        } catch (Exception e) {
            log.error("查询订单失败：" + e.getMessage(), e);
        }

        return R.fail("查询失败");
    }

    @Override
    public R<AdminOrderListByMonthDTO> findAdminOrderListByMonth(AdminOrderSearchParamDTO adminOrderSearchParamDTO) {
        Integer pageIndex = adminOrderSearchParamDTO.getPageIndex();
        Integer pageSize = adminOrderSearchParamDTO.getPageSize();
        Integer start = (pageIndex - 1) * pageSize;
        adminOrderSearchParamDTO.setStart(start);
        AdminOrderListByMonthDTO dto = new AdminOrderListByMonthDTO();

        try {
            Calendar c = Calendar.getInstance();
            SimpleDateFormat format = new SimpleDateFormat("yyyyMM");
            c.setTime(new Date());
            c.add(Calendar.MONTH, -11);
            Date m = c.getTime();
            String satrtTime = format.format(new Date());
            String endTime = format.format(m);
//            adminOrderSearchParamDTO.setStartDate(endTime);
//            adminOrderSearchParamDTO.setEndDate(satrtTime);
            List<AdminOrderByMonthDTO> tmp = new ArrayList<>();


         //   List<AdminOrderByMonthDTO> adminOrderByMonthDTO = baseMapper.searchAdminOrderListByMonth(adminOrderSearchParamDTO);
//            for (int i = 0; i < 12; i++) {
//                AdminOrderByMonthDTO list = new AdminOrderByMonthDTO();
//                Calendar vc = Calendar.getInstance();
//                vc.setTime(new Date());
//                vc.add(Calendar.MONTH, -i);
//                Date vm = vc.getTime();
//                String time = format.format(vm);
//                list.setBusiDate(time);
//                list.setTotal(0);
//                if (adminOrderByMonthDTO != null && adminOrderByMonthDTO.size() > 0) {
//                    for (AdminOrderByMonthDTO orderByMonthDTO : adminOrderByMonthDTO) {
//                        if (time.equals(orderByMonthDTO.getBusiDate())) {
//                            list.setTotal(orderByMonthDTO.getTotal());
//                            break;
//                        }
//                    }
//                }
//                adminOrderByMonthDTO.add(list);
//            }
//
//            dto.setTotal(adminOrderByMonthDTO.size());
//            dto.setAdminOrderByMonthDTO(adminOrderByMonthDTO);
//            return R.success(dto);
        } catch (
                Exception e) {
            log.error("查询订单失败：" + e.getMessage(), e);
        }

        return R.fail("查询失败");
    }

    @Override
    public R<AdminOrderListDTO> findAdminReturnOrderList(AdminOrderSearchParamDTO adminOrderSearchParamDTO) {

        Integer orderStatus = adminOrderSearchParamDTO.getOrderStatus();
        Integer keywordType = adminOrderSearchParamDTO.getKeywordType();
        String keyword = adminOrderSearchParamDTO.getKeyword();
        Integer returnType = adminOrderSearchParamDTO.getReturnType();
        Integer returnStatus = adminOrderSearchParamDTO.getReturnStatus();
        Integer dealType = adminOrderSearchParamDTO.getDealType();
        Integer start = (adminOrderSearchParamDTO.getPageIndex() - 1) * adminOrderSearchParamDTO.getPageSize();
        Integer pageSize = adminOrderSearchParamDTO.getPageSize();
//        try {
//            Integer total = baseMapper.searchAdminReturnOrderListCount(orderStatus, keywordType, keyword, returnStatus, returnType, dealType);
//            List<AdminOrderDTO> adminOrderDTOList = baseMapper.searchAdminReturnOrderList(orderStatus, keywordType, keyword, returnStatus, returnType, dealType, start, pageSize);
//            for (AdminOrderDTO orderDTO : adminOrderDTOList) {
//                orderDTO.setReturnStatus(transferReturnStatusForAdmin(orderDTO.getReturnType(), orderDTO.getReturnStatus()));
//                orderDTO.setOrderProductList(orderProductMapper.queryProductList(orderDTO.getOrderCode()));
//            }
//
//            AdminOrderListDTO orderListDTO = new AdminOrderListDTO();
//            orderListDTO.setTotal(total);
//            orderListDTO.setAdminOrderDTOList(adminOrderDTOList);
//            return R.success(orderListDTO);
//        } catch (Exception e) {
//            log.error("查询订单列表失败：" + e.getMessage(), e);
//        }

        return R.fail("查询订单列表失败");
    }

    /**
     * 转换成后台展示的数据 1-无售后/取消售后 2-售后中 3-售后成功 4-售后失败
     *
     * @param returnType
     * @param returnStatus
     * @return
     */
    private Integer transferReturnStatusForAdmin(Integer returnType, Integer returnStatus) {
        if (returnType == 0 || returnType == null || returnStatus == null) {
            return 1;
        }
        if (returnType == 1) {
            List<Integer> refunding = Arrays.asList(ReturnMoneyStatusEnum.AUDITING.getCode(),
                    ReturnMoneyStatusEnum.AUDIT_PASS.getCode(), ReturnMoneyStatusEnum.REFUNDING.getCode());
            if (returnStatus == ReturnMoneyStatusEnum.CANCELED.getCode()) {
                return 1;
            } else if (refunding.contains(returnStatus)) {
                return 2;
            } else if (returnStatus == ReturnMoneyStatusEnum.REFUND_SUC.getCode()) {
                return 3;
            } else if (returnStatus == ReturnMoneyStatusEnum.REFUND_FAIL.getCode()) {
                return 4;
            }
        } else {
            List<Integer> refunding = Arrays.asList(ReturnGoodsStatusEnum.AUDITING.getCode(),
                    ReturnGoodsStatusEnum.AUDIT_PASS.getCode(), ReturnGoodsStatusEnum.GOODS_RETURNING.getCode(),
                    ReturnGoodsStatusEnum.GOODS_RETURN_SUC.getCode(), ReturnGoodsStatusEnum.REFUNDING.getCode());
            if (returnStatus == ReturnGoodsStatusEnum.CANCELED.getCode()) {
                return 1;
            } else if (refunding.contains(returnStatus)) {
                return 2;
            } else if (returnStatus == ReturnGoodsStatusEnum.REFUND_SUC.getCode()) {
                return 3;
            } else if (returnStatus == ReturnGoodsStatusEnum.REFUND_FAIL.getCode()) {
                return 4;
            }
        }
        return 1;
    }

    @Override
    public R<AdminOrderDetailDTO> findAdminOrderDetail(IdQueryDTO idQueryDTO) {

        if (idQueryDTO == null || idQueryDTO.getId() == null) {
            return R.fail("参数错误");
        }

        try {
            Order order = baseMapper.selectById(idQueryDTO.getId());
            if (order == null) {
                return R.fail("订单不存在");
            }

            AdminOrderDetailDTO orderDetailDTO = dozerUtils.map(order, AdminOrderDetailDTO.class);
            /*
            OrderPayment orderPayment = orderPaymentMapper.selectOne(Wraps.<OrderPayment>lbQ().eq(OrderPayment::getOrderCode,order.getOrderCode()));
            if(orderPayment!=null){
                orderDetailDTO.setPayChannel(orderPayment.getPayChannel());
                orderDetailDTO.setPayNum(orderPayment.getPayNum());
            }
            */

            Long mid = order.getMid();

            Integer orderCount = baseMapper.selectCount(Wraps.<Order>lbQ().eq(Order::getMid, mid).ne(Order::getParentId, 0));
            orderDetailDTO.setOrderCount(orderCount);

            String tenantCode = BaseContextHandler.getTenant();
            //log.info("tenantCode:"+tenantCode);
            BaseContextHandler.setTenant(null);
            Member member = memberService.getById(mid);
            if (member != null) {
                orderDetailDTO.setMemberAccount(member.getNickname());
            }
            BaseContextHandler.setTenant(tenantCode);

            List<OrderProduct> orderProductList = orderProductMapper.selectList(Wraps.<OrderProduct>lbQ().eq(OrderProduct::getOrderId, order.getId()));
            List<OrderProductDTO> orderProductDTOList = dozerUtils.mapList(orderProductList, OrderProductDTO.class);
            orderDetailDTO.setOrderProductDTOList(orderProductDTOList);

            if (order.getReturnType() != null && order.getReturnType() == ReturnTypeEnum.RETURN_MONEY.getCode()) {
                List<MoneyReturn> moneyReturnList = moneyReturnMapper.selectList(Wraps.<MoneyReturn>lbQ().eq(MoneyReturn::getOrderId, order.getId()).eq(MoneyReturn::getCurrentVersion, 0));
                orderDetailDTO.setMoneyReturnList(moneyReturnList);

                List<MoneyReturnActionHistory> moneyReturnActionHistoryList = moneyReturnActionHistoryMapper.selectList(Wraps.<MoneyReturnActionHistory>lbQ().eq(MoneyReturnActionHistory::getOrderId, order.getId())
                        .eq(MoneyReturnActionHistory::getIsDelete, 0)
                        .orderByDesc(MoneyReturnActionHistory::getCreateTime));
                orderDetailDTO.setMoneyReturnActionHistoryList(moneyReturnActionHistoryList);
            }

            if (order.getReturnType() != null && order.getReturnType() == ReturnTypeEnum.RETURN_GOODS.getCode()) {
                List<GoodsReturn> goodsReturnList = goodsReturnMapper.selectList(Wraps.<GoodsReturn>lbQ().eq(GoodsReturn::getOrderId, order.getId()).eq(GoodsReturn::getCurrentVersion, 0));
                orderDetailDTO.setGoodsReturnList(goodsReturnList);

                List<GoodsReturnActionHistory> goodsReturnActionHistoryList = goodsReturnActionHistoryMapper.selectList(Wraps.<GoodsReturnActionHistory>lbQ().eq(GoodsReturnActionHistory::getOrderId, order.getId())
                        .eq(GoodsReturnActionHistory::getIsDelete, 0)
                        .orderByDesc(GoodsReturnActionHistory::getCreateTime));
                orderDetailDTO.setGoodsReturnActionHistoryList(goodsReturnActionHistoryList);
            }

            return R.success(orderDetailDTO);
        } catch (Exception e) {
            log.error("查询订单详情失败:" + e.getMessage(), e);
        }

        return R.fail("查询订单详情失败");
    }

    @Override
    public R<Integer> closeOvertimeOrder() {
        //超时时间暂定为15分钟
        long overTime = 15 * 60 * 1000;
        Date overDate = new Date(System.currentTimeMillis() - overTime);
        return R.success(baseMapper.closeOvertimeOrder(overDate));
    }

    @Override
    public R<Integer> autoReceiveGoods() {
        //超时时间暂定为7天
        long overTime = 7 * 24 * 60 * 60 * 1000;
        Date overDate = new Date(System.currentTimeMillis() - overTime);
        //查询出已发货超过7天，没有售后，并且用户没有确认自动收货的订单
        List<Order> orderList = baseMapper.selectList(Wraps.<Order>lbQ().eq(Order::getOrderStatus, OrderStatusEnum.NO_RECEIVE.getCode())
                .eq(Order::getIsDelete, YesOrNoEnum.NO.getCode())
                .lt(Order::getSendTime, overDate)
                .eq(Order::getReturnType, ReturnTypeEnum.NO_RETURN.getCode()));
        for (Order order : orderList) {
//            List<OrderProduct> orderProducts = orderProductMapper.selectByOrderId(order.getId());
//            List<Long> listIds = new ArrayList<>();
//            for (OrderProduct orderProduct : orderProducts) {
//                listIds.add(orderProduct.getId());
//            }
            orderEventUtil.publishOrderFinishEvent(order);

        }

        return R.success(baseMapper.autoReceiveGoods(overDate));
    }


    private Order setReceAdd(Long mid, Order order, Long receaddId) {
        if (order == null) {
            return null;
        }
        if (receaddId != null) {
            MemberAddress memberAddress = memberAddressService.getById(receaddId);
            if (memberAddress == null) {
                throw new BizException("收货地址信息有误，无法下单");
            }
            order.setProvince(memberAddress.getProvince());
            order.setCity(memberAddress.getCity());
            order.setDistrict(memberAddress.getArea());
            order.setAddress(memberAddress.getAddress());
            order.setRecName(memberAddress.getUsername());
            order.setRecMobile(memberAddress.getPhone());
        }
        return order;
    }

    /**
     * 调用微信支付
     *
     * @return
     * @author JustArgo 2020/5/25 17:51
     */
    private WxPayMpOrderResult wxPay(String outTradeNo, Long sum, String openId, String ip, String orderInfo) {
        WxPayUnifiedOrderRequest request = new WxPayUnifiedOrderRequest();

        //商户订单号
        request.setOutTradeNo(outTradeNo);
        //微信用户ID
        request.setOpenid(openId);
        //内容
        request.setBody(outTradeNo);
        //总金额  单位：分
        request.setTotalFee(sum.intValue());
        //终端IP
        request.setSpbillCreateIp(ip);
        //埋点支付
        return payService.unifiedOrder(request);
        /*if(StringUtil.isNotBlank(result.getPrepayId())){
            return result.getPrepayId();
        }

        return null;*/
    }

    private WxPayAppOrderResult wxPay2(String outTradeNo, Long sum, String openId, String ip, String orderInfo) {
        WxPayUnifiedOrderRequest request = new WxPayUnifiedOrderRequest();

        //商户订单号
        request.setOutTradeNo(outTradeNo);
        //微信用户ID
        request.setOpenid(openId);
        //内容
        request.setBody(outTradeNo);
        //总金额  单位：分
        request.setTotalFee(sum.intValue());
        //终端IP
        request.setSpbillCreateIp(ip);
        //埋点支付
        return payService.unifiedOrder(request);
    }

    private AlipayTradeAppPayResponse aliPay(String outTradeNo, Long sum, String openId, String ip, String orderInfo) {
        AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
        model.setOutTradeNo(outTradeNo);
        model.setTotalAmount(String.valueOf((sum.intValue() * 1.0 / 100)));
        model.setSubject(orderInfo);
        model.setBody(orderInfo);
        model.setTimeoutExpress("30m");
        model.setProductCode("FAST_INSTANT_TRADE_PAY");
        return payService.unifiedOrder(model);
    }

    @Override
    public Map<String, Object> countTodayOrder(Map<String, Object> param) {
      //  return this.getBaseMapper().countTodayOrder(param);
        return null;
    }

    @Override
    public R<Boolean> delReturnOrder(Long mid, IdTypeQueryDTO idTypeQueryDTO) {
        if (mid == null || idTypeQueryDTO == null || idTypeQueryDTO.getId() == null || idTypeQueryDTO.getType() == null) {
            return R.fail("参数错误");
        }
        if (idTypeQueryDTO.getType() == ReturnTypeEnum.RETURN_MONEY.getCode()) {
            MoneyReturn moneyReturn = new MoneyReturn();
            moneyReturn.setIsDelete(1);
            moneyReturnMapper.update(moneyReturn, Wraps.<MoneyReturn>lbQ().eq(MoneyReturn::getMid, mid).eq(MoneyReturn::getId, idTypeQueryDTO.getId()));
        } else {
            GoodsReturn goodsReturn = new GoodsReturn();
            goodsReturn.setIsDelete(1);
            goodsReturnMapper.update(goodsReturn, Wraps.<GoodsReturn>lbQ().eq(GoodsReturn::getMid, mid).eq(GoodsReturn::getId, idTypeQueryDTO.getId()));
        }
        return R.success();
    }

    @Override
    public R<String> generatePayQrCode(PayQrCodeDTO payQrCodeDTO) {
        if (payQrCodeDTO == null || StringUtils.isBlank(payQrCodeDTO.getBizId())
                || payQrCodeDTO.getSum() == null || payQrCodeDTO.getSum() <= 0) {
            return R.fail(-1, "参数错误，无法生成支付二维码");
        }

        WxPayUnifiedOrderRequest request = new WxPayUnifiedOrderRequest();

        //商户订单号
        request.setOutTradeNo(payQrCodeDTO.getBizId());

        //商品id
        request.setProductId(payQrCodeDTO.getBizId());

        //微信用户ID
        //request.setOpenid(openId);
        //内容
        request.setBody("保证金缴纳");
        //总金额  单位：分
        request.setTotalFee(payQrCodeDTO.getSum().intValue());
        //终端IP
        request.setSpbillCreateIp(payQrCodeDTO.getIp());
        //设置支付方式
        request.setTradeType(WxPayConstants.TradeType.NATIVE);

        DepositPromotionDTO depositPromotionDTO = new DepositPromotionDTO();
        depositPromotionDTO.setDepositType(DepositTypeEnum.PROMOTION.toString());
        depositPromotionDTO.setPromotionId(payQrCodeDTO.getPromotionId());
        depositPromotionDTO.setTenantCode(BaseContextHandler.getTenant());
        request.setAttach(JSON.toJSONString(depositPromotionDTO));

        WxPayNativeOrderResult result = payService.unifiedOrder(request);
        if (result != null && result.getCodeUrl() != null) {
            return R.success(result.getCodeUrl());
        }

        return R.fail(-1, "生成二维码失败");
    }

    @Override
    public R<String> queryPayQrCodeResult(String orderId) {
        WxPayOrderQueryRequest request = new WxPayOrderQueryRequest();
        request.setOutTradeNo(orderId);
        WxPayOrderQueryResult result = payService.queryOrder(request);
        log.info("result:" + JSON.toJSONString(result));
        if (WXPayConstants.SUCCESS.equals(result.getReturnCode()) && WXPayConstants.SUCCESS.equals(result.getResultCode())) {
            if (WXPayConstants.SUCCESS.equals(result.getTradeState())) {
                return R.success(result.getTransactionId());
            }
        } else {
            return R.fail(-1, "查询异常");
        }
        return R.success("");
    }

    @Override
    public MemberOrderStatistics getOrderStatisticsByMid(Long mid) {
        MemberOrderStatistics statistics = new MemberOrderStatistics();
        Integer orderCount = baseMapper.selectCount(Wraps.<Order>lbQ().eq(Order::getMid, mid).ne(Order::getParentId, 0));
        statistics.setOrderCount(orderCount);

        Integer payOrderCount = baseMapper.selectCount(Wraps.<Order>lbQ().eq(Order::getMid, mid)
                .eq(Order::getPayStatus, PayStatusEnum.PAYED.getCode()).ne(Order::getParentId, 0));
        statistics.setPayOrderCount(payOrderCount);

        Long orderSum = baseMapper.selectOrderSumByMid(mid);
        statistics.setOrderSum(orderSum);

        Integer buyProudctCount = baseMapper.selectBuyProductCount(mid);
        statistics.setBuyProductCount(buyProudctCount);

        Integer moneyReturnCount = moneyReturnMapper.selectCount(Wraps.<MoneyReturn>lbQ().eq(MoneyReturn::getMid, mid));
        Integer goodsReturnCount = goodsReturnMapper.selectCount(Wraps.<GoodsReturn>lbQ().eq(GoodsReturn::getMid, mid));
        statistics.setReturnCount(moneyReturnCount + goodsReturnCount);

        Integer returnOrderCount = baseMapper.selectReturnOrderCount(mid);
        statistics.setReturnOrderCount(returnOrderCount);

        Integer moneyReturnSucCount = moneyReturnMapper.selectCount(Wraps.<MoneyReturn>lbQ().eq(MoneyReturn::getMid, mid)
                .eq(MoneyReturn::getStatus, ReturnMoneyStatusEnum.REFUND_SUC.getCode()));
        Integer goodsReturnSucCount = goodsReturnMapper.selectCount(Wraps.<GoodsReturn>lbQ().eq(GoodsReturn::getMid, mid)
                .eq(GoodsReturn::getStatus, ReturnGoodsStatusEnum.REFUND_SUC.getCode()));

        statistics.setReturnSucCount(moneyReturnSucCount + goodsReturnSucCount);

        Double percent = 0d;
        if (statistics.getReturnCount() != 0) {
            percent = (moneyReturnSucCount + goodsReturnSucCount) / 1.0 / (moneyReturnCount + goodsReturnCount);
        }
        statistics.setReturnSucPercent(new BigDecimal(percent).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());

        return statistics;
    }

    @Override
    public ShippingDTO getShippingTrace(String shipperCode, String logisticCode) {
        try {
            return kd100TrackQueryAPI.getOrderTracesByJson(shipperCode, logisticCode);
            /*
            String result2 = kdniaoTrackQueryAPI.getOrderTracesByJson(shipperCode, logisticCode);
            log.info("result:"+result);
            ShippingDTO dto = JSON.parseObject(result,ShippingDTO.class);
            return dto;
            */
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            e.printStackTrace();
        }
        return null;
    }


    @Override
    public R<ReturnDetailVO> getReturnDetail(Integer returnType, String returnCode) {
        if (returnType == null || returnCode == null) {
            return R.fail(ExceptionCode.ILLEGALA_ARGUMENT_EX);
        }
        ReturnDetailVO returnDetailVO = null;
        if (returnType == ReturnTypeEnum.RETURN_MONEY.getCode()) {
            MoneyReturn moneyReturn = moneyReturnMapper.selectOne(Wraps.<MoneyReturn>lbQ().eq(MoneyReturn::getReturnCode, returnCode));
            if (moneyReturn == null || moneyReturn.getIsDelete() == 1) {
                return R.fail(ExceptionCode.NOT_FOUND.getCode(), "该售后单不存在或已删除");
            }
            returnDetailVO = dozerUtils.map(moneyReturn, ReturnDetailVO.class);
            returnDetailVO.setReturnType(returnType);
            Store store = storeService.findByTenantCode(moneyReturn.getTenantCode());
            if (store != null) {
                returnDetailVO.setStoreId(store.getId());
                returnDetailVO.setStoreName(store.getStoreName());
            }

            List<ReturnIntervention> riList = returnInventionMapper.selectList(Wraps.<ReturnIntervention>lbQ().eq(ReturnIntervention::getReturnCode, moneyReturn.getReturnCode()));
            if (riList != null && riList.size() > 0) {
                returnDetailVO.setReturnIntervention(riList.get(0));
            }

            returnDetailVO.setMoneyReturnActionHistoryList(new ArrayList<>());
            returnDetailVO.setGoodsReturnActionHistoryList(new ArrayList<>());

            String opIds = moneyReturn.getOrderProductIds();
            if (opIds != null) {
                List<Long> opIdList = new ArrayList<>();
                for (String opId : opIds.split(",")) {
                    opIdList.add(Long.valueOf(opId));
                }
                List<OrderProduct> opList = orderProductMapper.selectBatchIds(opIdList);
                List<OrderProductVO> opVOList = dozerUtils.mapList(opList, OrderProductVO.class);
                returnDetailVO.setOrderProductVOList(opVOList);

                int auditRejectCount = 0;
                List<MoneyReturnActionHistory> moneyReturnActionHistoryList = moneyReturnActionHistoryMapper.selectList(Wraps.<MoneyReturnActionHistory>lbQ().eq(MoneyReturnActionHistory::getReturnCode, moneyReturn.getReturnCode())
                        .eq(MoneyReturnActionHistory::getIsDelete, 0)
                        .orderByDesc(MoneyReturnActionHistory::getCreateTime));
                returnDetailVO.getMoneyReturnActionHistoryList().addAll(moneyReturnActionHistoryList);
                for (MoneyReturnActionHistory ah : moneyReturnActionHistoryList) {
                    if (ah.getStatus() == ReturnMoneyStatusEnum.AUDIT_REJECT.getCode()) {
                        auditRejectCount++;
                    }
                }
                if (auditRejectCount >= 2 && returnDetailVO.getReturnIntervention() == null) {
                    returnDetailVO.setCanApplyIntervention(1);
                } else {
                    returnDetailVO.setCanApplyIntervention(0);
                }
                for (OrderProductVO opVO : opVOList) {
                    opVO.setReturnType(ReturnTypeEnum.RETURN_MONEY.getCode());
                    opVO.setReturnStatus(returnDetailVO.getStatus());
                    opVO.setCanApplyIntervention(returnDetailVO.getCanApplyIntervention());
                }
            }
        } else {
            GoodsReturn goodsReturn = goodsReturnMapper.selectOne(Wraps.<GoodsReturn>lbQ().eq(GoodsReturn::getReturnCode, returnCode));
            if (goodsReturn == null || goodsReturn.getIsDelete() == 1) {
                return R.fail(ExceptionCode.NOT_FOUND.getCode(), "该售后单不存在或已删除");
            }
            returnDetailVO = dozerUtils.map(goodsReturn, ReturnDetailVO.class);
            returnDetailVO.setReturnType(returnType);
            Store store = storeService.findByTenantCode(goodsReturn.getTenantCode());
            if (store != null) {
                returnDetailVO.setStoreId(store.getId());
                returnDetailVO.setStoreName(store.getStoreName());
                returnDetailVO.setRefundAddress(store.getRefundAddress());
                returnDetailVO.setRefundContact(store.getRefundContact());
                returnDetailVO.setRefundTel(store.getRefundTel());
            }
            List<ReturnIntervention> riList = returnInventionMapper.selectList(Wraps.<ReturnIntervention>lbQ().eq(ReturnIntervention::getReturnCode, goodsReturn.getReturnCode()));
            if (riList != null && riList.size() > 0) {
                returnDetailVO.setReturnIntervention(riList.get(0));
            }

            returnDetailVO.setMoneyReturnActionHistoryList(new ArrayList<>());
            returnDetailVO.setGoodsReturnActionHistoryList(new ArrayList<>());

            String opIds = goodsReturn.getOrderProductIds();
            if (opIds != null) {
                List<Long> opIdList = new ArrayList<>();
                for (String opId : opIds.split(",")) {
                    opIdList.add(Long.valueOf(opId));
                }
                List<OrderProduct> opList = orderProductMapper.selectBatchIds(opIdList);
                List<OrderProductVO> opVOList = dozerUtils.mapList(opList, OrderProductVO.class);
                returnDetailVO.setOrderProductVOList(opVOList);

                int auditRejectCount = 0;
                List<GoodsReturnActionHistory> goodsReturnActionHistoryList = goodsReturnActionHistoryMapper.selectList(Wraps.<GoodsReturnActionHistory>lbQ().eq(GoodsReturnActionHistory::getReturnCode, goodsReturn.getReturnCode())
                        .eq(GoodsReturnActionHistory::getIsDelete, 0)
                        .orderByDesc(GoodsReturnActionHistory::getCreateTime));
                returnDetailVO.getGoodsReturnActionHistoryList().addAll(goodsReturnActionHistoryList);
                for (GoodsReturnActionHistory gh : goodsReturnActionHistoryList) {
                    if (gh.getStatus() == ReturnGoodsStatusEnum.AUDIT_REJECT.getCode()) {
                        auditRejectCount++;
                    }
                }
                if (auditRejectCount >= 2 && returnDetailVO.getReturnIntervention() == null) {
                    returnDetailVO.setCanApplyIntervention(1);
                } else {
                    returnDetailVO.setCanApplyIntervention(0);
                }
                for (OrderProductVO opVO : opVOList) {
                    opVO.setReturnType(ReturnTypeEnum.RETURN_GOODS.getCode());
                    opVO.setReturnStatus(returnDetailVO.getStatus());
                    opVO.setCanApplyIntervention(returnDetailVO.getCanApplyIntervention());
                }
            }
        }

        return R.success(returnDetailVO);
    }

    @Override
    public Map<String, Object> getOrderStatementOfAccount(String mid, Date time1, Date time2) {
        //return baseMapper.getOrderStatementOfAccount(mid, time1, time2);
        return null;
    }

    @Override
    public List<Order> getFinishOrderIdList() {
      //  return baseMapper.selectFinishOrderIdList();
        return null;
    }

    @Override
    public List<Long> getOrederIdByShoHuoAddress(AddressDTO dto) {

        //return baseMapper.getOrederIdByShoHuoAddress(dto);
        return null;
    }


    @Override
    public R<AdminOrderNumDTO> findAdminOrderNum() {
        AdminOrderSearchParamDTO adminOrderSearchParamDTO = new AdminOrderSearchParamDTO();
        adminOrderSearchParamDTO.setOrderStatus(2);
        AdminOrderNumDTO adminOrderNumDTO = new AdminOrderNumDTO();
        adminOrderNumDTO.setWaitOrderNum(baseMapper.searchAdminOrderListCount(adminOrderSearchParamDTO));
        adminOrderSearchParamDTO.setOrderStatus(3);
        adminOrderNumDTO.setSendOrderNum(baseMapper.searchAdminOrderListCount(adminOrderSearchParamDTO));
        adminOrderSearchParamDTO.setOrderStatus(4);
        adminOrderNumDTO.setOverOrderNum(baseMapper.searchAdminOrderListCount(adminOrderSearchParamDTO));
        adminOrderSearchParamDTO.setOrderStatus(5);
        adminOrderNumDTO.setCloseOrderNum(baseMapper.searchAdminOrderListCount(adminOrderSearchParamDTO));
        return R.success(adminOrderNumDTO);
    }

    @Override
    public Map storeAll(Store store) {
        AdminOrderSearchParamDTO a = new AdminOrderSearchParamDTO();
        a.setSource(0);
        a.setOrderStatus(4);
        a.setStart(0);
        a.setPageSize(9999999);
        List<AdminOrderDTO> orders = baseMapper.searchAdminOrderList(a);
        int allOrderAmount = 0;
        int allOrderNum = 0;
        for (AdminOrderDTO adminOrderDTO : orders) {
            if (adminOrderDTO.getOrderStatus() == 4) {
                allOrderAmount = (int) (allOrderAmount + adminOrderDTO.getPaySum());
                allOrderNum++;
            }
        }

        Map<String, Object> map = new HashMap<>();
        map.put("allOrderAmount", allOrderAmount);
        map.put("allOrderNum", allOrderNum);
        return map;
    }


    /**
     * 将分转成元
     *
     * @return
     * @author JustArgo 2020/5/30 21:36
     */
    private BigDecimal transferMoney(Long fee) {
        return new BigDecimal(fee / 1.0 / 100).setScale(2, BigDecimal.ROUND_HALF_UP);
    }


    @Override
    public boolean saveBatchSomeColumn(List<Order> entityList) {
        return false;
    }
}
